在PHP中包含文件的最佳方法是什么?

5

我正在开发一个PHP Web应用程序,想知道在代码可维护的前提下,包含文件的最佳方式是什么(使用include_once)。所谓可维护性是指,如果我想移动一个文件,可以轻松地重构我的应用程序,使其正常工作。

由于我试图遵循良好的面向对象编程实践(一个类=一个文件),因此我有很多文件。

以下是我应用程序的典型类结构:

namespace Controls
{
use Drawing\Color;

include_once '/../Control.php';

class GridView extends Control
{
    public $evenRowColor;

    public $oddRowColor;

    public function __construct()
    {
    }

    public function draw()
    {
    }

    protected function generateStyle()
    {
    }

    private function drawColumns()
    {
    }
}
}

我也曾经有过这个问题,我得出的结论是PHP确实没有一个非常好的包管理系统。不过Netbeans确实有所帮助。 - Dhaivat Pandya
2个回答

6

我曾经在所有的php文件中都使用以下代码开始:

include_once('init.php');

然后在那个文件中,我会require_once所有需要被引用的其他文件,比如functions.php或者globals.php,这里我会声明所有的全局变量或常量。这样你只需要在一个地方编辑所有的设置。


3
为了让代码更易于维护,你可以将初始化文件的路径(我通常称之为配置文件)定义为环境变量。无论应用程序的目录结构有多深,每个文件都可以导入 $_ENV['my_app_config'] ,而不必担心像 include_once('../../../init.php') 这样的问题。 - user35288

4

这取决于你想要实现的目标。

如果你想要在文件和它们所在的目录之间建立可配置的映射关系,你需要设计一个路径抽象并实现一些加载函数来处理它。我会举一个例子。

假设我们使用类似 Core.Controls.Control 的表示法来引用(物理)文件 Control.php,该文件位于(逻辑)目录 Core.Controls 中。我们需要进行两部分实现:

  1. 告诉我们的加载器,Core.Controls 映射到物理目录 /controls
  2. 在该目录中搜索 Control.php

因此,以下是一个起点:

class Loader {
    private static $dirMap = array();

    public static function Register($virtual, $physical) {
        self::$dirMap[$virtual] = $physical;
    }

    public static function Include($file) {
        $pos = strrpos($file, '.');
        if ($pos === false) {
            die('Error: expected at least one dot.');
        }

        $path = substr($file, 0, $pos);
        $file = substr($file, $pos + 1);

        if (!isset(self::$dirMap[$path])) {
            die('Unknown virtual directory: '.$path);
        }

        include (self::$dirMap[$path].'/'.$file.'.php');
    }
}

您可以这样使用加载器:
// This will probably be done on application startup.
// We need to use an absolute path here, but this is not hard to get with
// e.g. dirname(_FILE_) from your setup script or some such.
// Hardcoded for the example.
Loader::Register('Core.Controls', '/controls');

// And then at some other point:
Loader::Include('Core.Controls.Control');

当然,这个示例只是最基本的有用操作,但您可以看到它允许您做什么。

如果我犯了任何小错误,请原谅,我边打字边进行。


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