组织PHP包括在您的开发环境中

时间:2011-01-07 00:51:05

标签: php code-organization

我正在根据Chris Shiflett的优秀Essential PHP Security审核我的网站设计。

我想采用的其中一个建议是将所有可能的文件移出webroot,其中包括include。

在我的共享主机上这样做很简单,但我想知道人们如何在他们的开发测试平台上处理这个问题?

目前我已配置XAMPP安装,以便localhost/mysite/D:\mysite\匹配,其中包含D:\mysite\includes\

为了保持包含路径准确,我猜我需要在本地磁盘上复制服务器的路径?像D:\mysite\public_html\

这样的东西

有更好的方法吗?

3 个答案:

答案 0 :(得分:6)

这似乎是很多php开发人员的一个难点,所以让我们好好解决它。大多数PHP应用程序都使用include '../../library/someclass.php.class'来丢弃代码。这对任何人来说都不是很好,因为它很容易打破,而且当你应该编码时,没有人喜欢做路径清洁工作。这也有点像建造一个纸牌屋并巩固连接,因为害怕任何变化。好吧,也许我们可以创建一个常量,并使用完整路径?

define('PATH', '/home/me/webroot/Application');
include(PATH . '/Library/someclass.php.class');

那很好,但是嗯,如果我们在Windows上部署怎么办?另外,我们要在每个脚本入口点上定义路径吗?如果你问我,不是很干。此外,移动部署将是一个巨大的痛苦。显然,虽然我们距离更近,但并没有太大的改进。

幸运的是,PHP提供了一些可以立即帮助我们的魔术子弹功能。

因此,我们假设您的应用程序只有一个入口点,或者至少是一个共享头文件。如果我们知道头文件与代码根相关联,我们可以很快地获取我们的部署根。 IE,在/home/me/webroot/Application/Init/set_paths.php

define('PATH_SITE', realpath(dirname(__FILE__) . '/../../'));

太棒了,那就是我们的文档根目录。它是独立于操作系统的,如果你改变set_paths.php生活的地方,它很容易适应。现在我们可以在应用程序中讨论其他一些位置,只是因为常量很方便:

define('PATH_APPLICATION', realpath(PATH_SITE . "/Application"));
define('PATH_LIBRARY', realpath(PATH_SITE . "/Application/Library"));
define('PATH_CONFIG', realpath(PATH_SITE . "/Config"));
define('PATH_WRITE', realpath(PATH_SITE . "/Volatile"));

这一切都非常好,但它并不比我们以前的解决方案好多少。输入PHP包含路径。通过在路径中添加相关常量,我们不需要每次都定义它们。包含路径中的路径顺序实际上对速度非常重要,因此我们会尽一切努力按使用顺序排列它们。

$paths['inc'] = array_flip(explode(PATH_SEPARATOR, get_include_path()));
unset($paths['inc']['.']);
$paths['inc'] = array_flip($paths['inc']);

// The first item on the path the external
// libs that get used all the time,  
// then the application path, then the
// site path, and any php configured items.
// The current directory should be last.

$paths = array_merge(array(PATH_LIBRARY, PATH_APPLICATION, PATH_SITE), $paths['inc'], array("."));
set_include_path(implode(PATH_SEPARATOR, $paths));

现在,我们应用程序中的所有关键位置都在路径上,无论您决定存储库,设置等,您都可以将内容包含在内容中。

include('someclass.php.class');

更进一步

如果您正在使用设计合理的OOP应用程序,我们可以更进一步。如果您订阅了一个文件,一个类,那么PEAR命名约定会让生活变得非常简单。

  

PEAR命名约定规定了文件系统和类之间的1:1关系。例如,可以在include_path上的文件“Foo / Bar / Baz.php”中找到类Foo_Bar_Baz。   source

一旦你有一个可预测的文件到类的映射,你就可以实现spl_autoload_register而你可以替换

include('someclass.php.class');
new SomeClass();

只需

new SomeClass();

让PHP为你处理它。

答案 1 :(得分:4)

是的,还有更好的方法。您应始终使用相对路径,如include('./includes/foo.php');中所示。如果您的路径是相对路径,则不必担心本地路径,除非它们应与网站的整体结构相匹配(./includes可以引用本地计算机上的D:\projects\web\foo-page\includes并{{1 }} 在网站上)。

或者,使用本地计算机或虚拟机上的Web服务器来模拟生产环境;在正确配置的环境中,/home/andrew/foo-page/includes将引用您的/,而不是您的根目录(如Windows上的文件系统wwwroot/)。

答案 2 :(得分:1)

您可以始终拥有相对包含路径。要么只是做要求(“../../ something”); 而不是要求(“D:\ something \ something”); (当然,在这种情况下,你必须确保路径前的..的数量是正确的。(..表示转到父目录)),或者,如果你的包含结构非常复杂,你可以使用< strong> FILE 常量,总是指向当前正在执行的php文件。您可以获取该值,然后解析我们所需的文件路径。

最后,如果您希望尽可能保持文件结构与生产服务器中的文件结构完全相同,但又不想将大量文件保存在不同位置,请查找联结http://en.wikipedia.org/wiki/NTFS_junction_point以获取窗口或符号链接对于* nix。 这样你就可以使用联结构建正确的路径,同时保持原始文件的位置,从而只保留1个版本的文件。