我正在设置一个php项目,但我不太熟悉如何正确使用php的include/require命令.我的布局目前看起来像这样:
/public --apache points into this directory /public/index.php /public/blah/page.php /utils/util1.php -- useful classes/code are stored in other directories out here /dbaccess/db1.php dbaccess/db1.php require '../utils/util1.php
公共/ index.php文件
require '../dbaccess/db1.php'
公共/胡说/ page.php文件
require '../../dbaccess/db1.php'
问题来自php'include'文档:
如果filename以./或../开头,则仅在当前工作目录中查找
所以public/blah/page.php失败了,因为它包含dbaccess/db1.php,它在尝试包含util1.php时会爆炸.它失败了,因为它的相对路径来自public/blah /中的原始脚本,而不是来自dbaccess /
这看起来非常愚蠢 - db1.php必须知道它被包含在哪里不起作用.
我见过这样的策略:
require_once dirname(__FILE__) . '/../utils/util1.php');
这显然是有效的,因为现在这条道路是绝对的道路,但对我来说似乎真的很奇怪.
这是正常的吗?我应该继续沿着这条路走下去,还是我错过了一些明显的东西?
通常,标准约定是这样的:像@grepsedawk所说,你需要定义一个包含项目文件夹根目录的常量,如果你能包含你的包文件夹的根:
define('APP_ROOT', dirname(__FILE__)); define('INCLUDE_ROOT', APP_ROOT . "/includes");
注意:常量名称必须是一个字符串!
此外,你会注意到我正在使用dirname(__FILE__);
.如果将常量定义文件放在子目录中,则可以执行a dirname(dirname(__FILE__));
,这相当于a ../
.
现在还有其他一些警告.虽然PATH_SEPARATOR
是一个很酷的常数,但它不是必需的.Windows在路径名中接受/或\,并且由于Linux只有用户/作为路径分隔符,所以继续使用/而不是通过重复引用来修改代码PATH_SEPARATOR
.
现在您已经定义了根常量,当您需要包含配置文件时,您将要做的是一个简单的:
include INCLUDE_ROOT . '/path/to/some/file.php';
您可能希望define(...)
在根目录中的引导脚本中使用常量定义(上面的定义):
www_root/ index.php bootstrap.php
引导程序将包含定义(或include
常量文件的一个),以及include
每个页面都需要的任何文件.
最后你可能不会使用最后一个标准约定,但如果你开始进行面向对象编程,最常见的方法(PEAR标准)是使用_来分隔命名空间来命名你的类:
class GlobalNamespace_Namespace_Class //...
然后组织你的文件结构映射名称空间到子目录(字面上用/'替换所有_):
include_dir/ GlobalNamespace/ Namespace/ Class.php
并使用__autoload()
函数加载您的类,但这是另一个问题.