PHP路径的最佳实践

19

我在互联网上搜索了很多,想找到处理网站路径的最佳方法。应该使用相对路径、绝对路径还是其他方式?

我看到有人几次提到dirname (FILE)。 相对路径存在一个问题,就是被多个文件在不同目录级别中包含的PHP文件会导致相对路径失效。例如,如果目录结构是:

Root
    A
    B
       b

如果一个 PHP 文件在 b 中,并且包含了 B 中的另一个文件,则文件中的代码相对路径将会不同。

因此,一般来说,在处理包含和文件操作时,处理文件路径的最佳方法是什么。


这就是“最佳”任何事物的问题,它几乎总是主观的。 - user557846
5个回答

15

虽然有许多方法可以查找路径,但我总是觉得最简单的方法是在项目根目录下的文件(例如index.php或类似的config文件)中定义一个常量。 然后,我可以使用SITE_ROOT来包含/类加载等,使用SITE_URL来进行视图、控制器、重定向等操作。

<?php
$root=pathinfo($_SERVER['SCRIPT_FILENAME']);
define ('BASE_FOLDER', basename($root['dirname']));
define ('SITE_ROOT',    realpath(dirname(__FILE__)));
define ('SITE_URL',    'http://'.$_SERVER['HTTP_HOST'].'/'.BASE_FOLDER);
?>

基础类自动加载器

<?php
function __autoload($class_name) {
    include (SITE_ROOT.'/includes/'.$class_name.'.php');
}
$obj  = new MyClass1();
$obj2 = new MyClass2(); 
?>

使用这种方法,所有将要使用自动加载程序的文件都需要包含配置文件。如果是这样的话,最好的方法是使用相对路径,如include('../../config.php'); 此外,就像我上面提到的,如果不是所有文件都是OO的,那么这个方法还能行吗? - Nath5
在您的索引文件中定义常量,它只需要指向您的根目录,如果您的配置在根目录中,则只需执行 include(SITE_ROOT.'/config.php'),无论您调用该包含多深,它始终指向同一文件。当调用类时,__autoload 仅起作用,它可以节省为每个类执行 include (SITE_ROOT.'/includes/'.$class_name.'.php'); 的时间,对于 MVC 模式中的模型非常有用,因为控制器通常从路由器/前端控制器类中调用。 - Lawrence Cherone
2
我不太明白这如何解决我的问题。即使我在根目录中有此配置级别,所有其他文件仍然需要使用相对路径进行包含。我遇到的问题的一个例子是,我有一个ErrorReporter类,它被所有其他文件包含,这些文件位于目录结构中的不同级别。在ErrorReporter类内部,我有一些路径,但如果它们是相对路径,则会相对于包含ErrorReporter的任何类,这意味着它们不会每次都相对于相同的位置。 - Nath5

0
你可以将所有的include文件放入一个主目录中。然后在配置文件或脚本本身中创建一个路径变量,指向include目录。

1
这样做是可行的,但它会破坏我的组织结构。我试图保持我的文件在一个逻辑目录结构中,因为有很多文件。 - Nath5

0

在目录结构、PHP文件和类名方面使用适当的命名约定,并设计一个自动加载器来包含文件,是使用最佳实践的方式。


你有没有创建自动加载器的好例子链接?我对PHP还很陌生,还没有找到好的教程。 - Nath5
http://php.net/manual/en/language.oop5.autoload.php - Lawrence Cherone
谢谢,我看过了,但那似乎只适用于面向对象的代码,我有一些文件不是面向对象的,所以我猜这种方法行不通。 - Nath5

0

Zend框架提供了一些关于优化包含路径的好建议:

http://framework.zend.com/manual/1.10/en/performance.classloading.html

即使您不使用Zend框架,这些都是很好的指针。一般的要点如下:

  • 使用绝对路径
  • 减少定义的包含路径数量
  • 最后定义当前目录,或者根本不定义
  • 尽早定义您的Zend框架include_path(如果您不使用Zend,则不太相关)

-1
新版本的 PHP(PHP5.3)可以使用__autoload,所以你只需要确定你的应用程序根目录即可。

autoload会递归扫描目录路径吗?如果是的话,这似乎对性能不利。另外,autoload似乎只适用于类,我的一些文件不是面向对象的。 - Nath5
自 PHP 7.2 起,该函数已被弃用。 - Webdevotion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接