从不同的文件夹自动加载类

2022-08-30 11:19:00

这就是我自动加载文件夹中所有类的方式,controllers

# auto load controller classes
    function __autoload($class_name) 
    {
        $filename = 'class_'.strtolower($class_name).'.php';
        $file = AP_SITE.'controllers/'.$filename;

        if (file_exists($file) == false)
        {
            return false;
        }
        include ($file);
    }

但是我在文件夹中也有类,我也想自动加载它们 - 我该怎么办?我应该复制上面的自动加载,只是将路径更改为(但这不是重复的吗??)?modelsmodels/

谢谢。

编辑:

这些是我在控制器文件夹中的类文件名:

class_controller_base.php
class_factory.php
etc

这些是我在模型文件夹中的类文件名:

class_model_page.php
class_model_parent.php
etc

这就是我通常如何命名我的控制器类类(我使用下划线和低写字母),

class controller_base 
{
...
}

class controller_factory
{
...
}

这就是我通常如何命名我的模型类类(我使用下划线和低写字母),

class model_page 
    {
    ...
    }

    class model_parent
    {
    ...
    }

答案 1

我看到您正在使用和作为类命名约定。controller_*****model_*****

我读了一篇很棒的文章,它建议使用php的替代命名约定。namespace

我喜欢这个解决方案,因为我把课程放在哪里并不重要。无论它在我的文件结构中的哪个位置,都会找到它。它还允许我随心所欲地称呼我的类。我不需要类命名约定即可使我的代码正常工作。__autoload

例如,您可以设置文件夹结构,例如:

  • 应用/
    1. 控制器/
      • 基地.php
      • 工厂.php
    2. 型号/
      • 页面.php
      • 家长.php

您的类可以按如下方式进行设置:

<?php
namespace application\controllers;
class Base {...}

和:

<?php
namespace application\models;
class Page {...}

自动加载机可能如下所示(或看到末尾的“自动加载说明”):

function __autoload($className) {
    $file = $className . '.php';
    if(file_exists($file)) {
        require_once $file;
    }
}

然后。。。您可以通过三种方式调用类:

$controller = new application\controllers\Base();
$model = new application\models\Page();

<?php
use application\controllers as Controller;
use application\models as Model;

...

$controller = new Controller\Base();
$model = new Model\Page();

<?php
use application\controllers\Base;
use application\models\Page;

...

$controller = new Base();
$model = new Page();

编辑 - 关于自动加载的说明:

我的主自动加载器看起来像这样:

// autoload classes based on a 1:1 mapping from namespace to directory structure.
spl_autoload_register(function ($className) {

    # Usually I would just concatenate directly to $file variable below
    # this is just for easy viewing on Stack Overflow)
        $ds = DIRECTORY_SEPARATOR;
        $dir = __DIR__;

    // replace namespace separator with directory separator (prolly not required)
        $className = str_replace('\\', $ds, $className);

    // get full name of file containing the required class
        $file = "{$dir}{$ds}{$className}.php";

    // get file if it is readable
        if (is_readable($file)) require_once $file;
});

这个自动加载器是类名到目录结构的直接1:1映射;命名空间是目录路径,类名是文件名。因此,上面定义的类将加载文件 。application\controllers\Base()www/application/controllers/Base.php

我将自动加载程序放入一个文件,bootstrap.php,它位于我的根目录中。这可以直接包含,也可以修改php.ini以auto_prepend_file,以便它自动包含在每个请求中。

通过使用spl_autoload_register您可以注册多个自动装入函数,以便以所需的任何方式装入类文件。也就是说,您可以将部分或全部类放在一个目录中,也可以将部分或全部命名空间类放在一个文件中。非常灵活的:)


答案 2

您应该命名类,以便下划线 () 转换为目录分隔符 ()。一些PHP框架可以做到这一点,例如Zend和Kohana。_/

因此,您命名您的类并将文件放入其中,然后您的自动加载确实...Model_Articleclasses/model/article.php

function __autoload($class_name) 
{
    $filename = str_replace('_', DIRECTORY_SEPARATOR, strtolower($class_name)).'.php';

    $file = AP_SITE.$filename;

    if ( ! file_exists($file))
    {
        return FALSE;
    }
    include $file;
}

另请注意,您可以使用spl_autoload_register()使任何函数成为自动加载函数。它也更灵活,允许您定义多个自动加载类型函数。

如果必须有多个自动加载函数,spl_autoload_register() 允许这样做。它有效地创建了一个自动加载函数队列,并按照它们定义的顺序运行每个函数。相比之下,__autoload() 只能定义一次。

编辑

注意:__autoload自 PHP 7.2.0 起已弃用。强烈建议不要依赖此功能。有关更多详细信息,请参阅 PHP 文档。http://php.net/manual/en/function.autoload.php


推荐