Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29956122
  • 博文数量: 2065
  • 博客积分: 10377
  • 博客等级: 上将
  • 技术积分: 21525
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:50
文章分类

全部博文(2065)

文章存档

2012年(2)

2011年(19)

2010年(1160)

2009年(969)

2008年(153)

分类:

2009-06-16 23:28:51

绝对原创]PHP中路径问题的解决方案 by longnetpro

引言:
关于PERL与PHP中的包含路径一直是一个比较难解的问题,主要是与操作系统和WEB服务器有关,不可能非常智能化的解决这个路径问题。相对于 PERL,PHP的路径好得多,解决起来也容易得多,因为PHP的相对路径在PHP程序中的任何场合都可以使用,而不象PERL在某些语句中必须用绝对路 径而导致移植的极其复杂。

基于此,在PHP中,我设计了一个绝对稳妥的解决方案,如下所述。

原则:
使用相对路径,但在相对路径中用绝对路径(有点绕,待会儿详解),一是可以保证可移植性,二是可以方便地修改,三是公式化且结构清晰明了,易于扩展。

步骤详解:
1、先确定好一个程序的根目录,注意是文件系统下的,不是WEB服务器下的虚拟目录,不过一般情况下该目录下的子目录的相对路径与URL下该目录的虚拟子目录是相同的。
2、在定义好的程序根目录下的每个子目录下(其实不一定是每个,根据需要)建立一个settings.php,里面定义一个变量或是常数(常数比 较好,因为作用域比较大),如APPROOT,但这个APPROOT却不是绝对路径,而是该目录相对于你指定的程序根目录的相对路径。

心得:第一步在我们的网站根此目录下定义好这个根此目录出来。
第二步:在我们的每个子此目录下都建立setting.php文件。这里面定义一个常量相对于我们的根目录的值

3、在此目录下的所有程序入口文件(也即第一个包含其它文件的文件,或是允许直接在浏览器中浏览的文件)中第一句写上 require_once('settings.php');,但要注意,所有被包含文件最好不要加此句——其实加上也可以,因为你可以在 settings.php中写上 if(!defined(APPROOT)) define(APPROOT, '../..');这类的语句以防重定 义。
4、如果你要包含其它文件,无论是直接还是间接地包含,都可以写成 include(APPROOT.$path);,这里$path为被包含文件相对于你所指定的程序根目录的绝对路径


心得:
1.定义好程序的根目录。
2.子此目录下面都建立好setting.php文件出来。里面的常量值是相对于根此目录的绝对路径。
  比如说 root\
            app\
               model\
                    a.php
               setting.php     定义的常量如果根此目录是 root\则此常量值将为 app\
3.想要包含进来其他的文件。
  include(APPROOT.$path)  $path : 要包含的文件相对于根目录的绝对路径值!



原理:
定下的程序根目录是相对路径,但具体的目录位置是相对于那个根目录的绝对路径,两者组合起来就是具体文件相对于程序根目录的相对路径了。例如目录 c:\wwwroot\app为你指定的程序根目录,然后有这么两个文件c:\wwwroot\app\a\index.php和c:\wwwroot \app\b\inc.php。对子目录a来说,APPROOT是'..',而对程序根目录来说,inc.php的绝对路径是$path='/b /inc.php',两者组合为'../b/inc.php'。如果要在index.php中包含inc.php就要写成include('../b /inc.php');,而这个路径不就正好是刚才组合而成的APPROOT.$path吗?


结论:
经过以上处理,各个路径绝对整齐划一,唯一罗嗦一点的就是每个目录下要定义一下这个APPROOT,但每个目录下只需在本目录的 settings.php中定义一次就足够了如果你整个程序只有一个入口文件,如index.php,而其它文件全部都是直接或是间接地被包含进这个唯 一的入口文件的话,就只需在index.php的所在目录下的settings.php中定义一次就OK了。如果有朋友做过Delphi的工程并对工程文 件研究过的话,就会发现我刚才说的一个程序只有一个主入口文件的情况与Delphi的工程十分相似,因为Delphi除了一个主程序文件(dpr文件), 其余的全部是单元文件或是资源文件,都不能独立执行。在PHP中,如果这种情况出现,只需定义一次APPROOT,并在主程序文件中第一句话写成 require_once('settings.php');,而以后所有的包含全都可以用include(APPROOT.$path);,就保证不会 有任何问题,除非你不会写这个“包含文件相对于程序根目录的绝对路径”$path。

这个方法我用了不止一次,收效很好。另外还可以参考JSP的WEB-INFO中路径的定义方式。

我这个是以不变应万变的公式化的方案,如果有朋友有更好的方案,欢迎提出讨论!如有不明白的也欢迎提出。


可以参考的另外一篇文章如下:

最后一种方式,也是采用公用文件定义路径的方式,这也是我常使用的方式,在我的应用中定义一个path.php文件,在文件中定义当前应用的全局路径变量 $ROOT_PATH,所有的应用文件都调用和包含path.php文件,这个文件可以放到php.ini的include_path设置的目录下,也可 以放到系统根 /下,也可以放到任何地方,只要的相对固定的,建议放到include_path定义的目录下,path.php文件根据当前访问的页面相对的 PHP_SELF值取得路径信息,然后通过计算的方式得出到网站相对根目录的相对路径,下面是我的path.php文件的计算$ROOT_PATH值的方 式:

/**
* 获取当前文件同指定网站相对根目录的目录层数 $ROOT_PATH   
* $ROOT_PATH 变量值末尾包含了路径的"/"符号,在引用时不要再加"/"
* example: $ROOT_PATH."images/logo.gif"
*/
$_self_path     = ($_SERVER['PHP_SELF'] == "" )? $_SERVER['REQUEST_URI'] : $PHP_SELF;
$_path_array    = explode("/",$_self_path);
$_path_count    = count($_path_array);
$ROOT_PATH  = "";
for ($i=0;$i<$_path_count-2;$i++)
{
    $ROOT_PATH = '../'.$ROOT_PATH;
}


这个$ROOT_PATH可以在系统任何地方使用,只需要在后面跟上目标文件相对网站目录根的相对路径即可,比如 $ROOT_PATH.'/images/test.gif' 

两者前者使用相对路径后者使用绝对路径
如果包含只有一层 那么两种方法效果是一样的 绝对路径 执行效率应该稍为高些
如果在包含的文件下再包含那么效果就不一样了 相对路径会以最后包含的文件为参照物寻找路径
绝对路经就不存在这个问题













阅读(1219) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-06-23 15:53:21

if(!define("approot")) define("approot","./") 这里写错了应该是 if(!defined("approot")) define("approot","./")

chinaunix网友2009-06-17 08:48:36

比如我现在的目录结构是这样的: web file a.php file1 b.php 那我可以在根目录下面设置好 一个setting.php文件。在里面我定义好一个常量 if(!define("approot")) define("approot","./") 表示根目录是当前目录。 那我们在index.php中可以这样来引入 require("setting.php") 然后如果你要包含进来其他的PHP文件的话那就可以这样来写的 include(approot."/a/a.php") 这样的话以后我们只需要修改这个常量就好了!