PHP:AutoLoader能够在一个php文件中加载多个类吗?

时间:2016-06-23 03:50:43

标签: php autoload

引自Autoloading Classes

  

许多编写面向对象应用程序的开发人员创建了一个PHP   每个类定义的源文件。其中一个最大的烦恼是   必须在开头写一长串所需的包括   每个脚本(每个类一个)。

     

在PHP 5中,不再需要这样做。 spl_autoload_register()   函数注册任意数量的自动加载器,启用类和   接口如果当前不是,则自动加载   定义。通过注册自动加载器,PHP将获得最后一次机会   在失败之前加载类或接口并出现错误。

问题是,如果单个php文件中有多个类,它是否适合自动加载?还是我必须使用require filepath声明?

例如,我在Protobuf \ Client.php下有一个协议文件:

<?php

namespace Protobuf;
class A {
...
}
class B {
...
}

4 个答案:

答案 0 :(得分:3)

您必须拥有一些复杂的功能才能从名为Client.php的文件中自动加载这些类。我们的想法是将您的namespace\classname翻译成directory\filename.php

在这种情况下,您需要为文件A.php命名,然后当您致电new Protobuf\A()时,它会找到它。否则,您将不得不创建一个过于复杂的自动加载器。

假设您确实创建了自动加载器,以便找到A类,然后您可以在同一个文件上使用B,但前提是您已经自动加载A,否则您有让一些algorythm知道AB在同一页面上。

我会使用上面的模式或像 Magento 这样的应用程序采用的模式,通过替换下划线将类名转换为目录路径:

$class = new Core_Classes_MyClass_Client();

您的自动加载器会替换下划线并将加载:

Core/Classes/MyClass/Client.php //or similar scheme

这对我来说是一种简单的方法,但我更喜欢使用命名空间和类。上面的方法目前并不受欢迎,从命名的角度来看,非常容易混淆,因为很多类可能在同一个文件夹中或嵌套在子文件夹中。你可以为课程命名很长。

答案 1 :(得分:1)

延伸Rasclatts非常翔实的答案,

理想情况下,在自动加载方面将类分开是一种很好的做法。我强烈建议寻找作曲家PSR-0命名空间自动加载

PSR-0允许您将所有课程精美地组织到具有无限深度的子文件夹中,采用以下文件夹结构

\system
 - Members
     - Members.php
 - Auth
     - Auth.php
 - Database
     - Database.php

对于这个例子,在上面的每个php文件中,在你的类声明之前你会有namespace MyNameSpace;,然后在你的composer.json中你会得到类似于(documentation)的东西:< / p>

"autoload": {
    "psr-0": { "MyNameSpace": "/system" }
}

Composer应安装在本地/主机上,以便您编译自动加载文件,打开终端并导航到项目目录并输入:

composer dump-autoload -o

现在一切都整齐有序,你可以访问类似于:

的类
\MyNameSpace\Auth::staticFunction();

答案 2 :(得分:1)

是,不, 但是,如果我为一个非常大的WSDL生成(自动)类和方法呢?

即。对于一百多个方法你可能有百个methodRequests(作为一个类对象),下一百个methodResponse(作为一个类对象)和大数组,即ClassMap。

有时最好在一个文件中处理这些东西,特别是在开发没有优秀的WSDL文档的情况下。

答案 3 :(得分:1)

要直接回答此问题,我们可以在classmap中将autoload用作composer.json,以支持包含多个类的单个文件。

例如,我们将支持单个文件Protobuf\Client.php,其中包含两个类AB

<?php

namespace Protobuf;

class A {
}

class B {
}

我们在classmap中添加composer.json,如下所示:

{
    "name": "hailong/myproj",
    "autoload": {
        "classmap": [
            "Protobuf/Client.php"
        ]
    }
}

然后,在main.php中,我们可以使用AB类:

<?php

require __DIR__.'/vendor/autoload.php';

use Protobuf\A;
use Protobuf\B;

$a = new A();

$b = new B();

最后,不要忘记在更改composer dump-autoload之后运行composer.json,这将神奇地生成autoload.php所需的main.php

对于尚未退出composer的人们来说,这是我们将获得的最终文件结构:

myproj % tree
.
├── Protobuf
│   └── Client.php
├── composer.json
├── main.php
└── vendor
    ├── autoload.php
    └── composer
        ├── ClassLoader.php
        ├── LICENSE
        ├── autoload_classmap.php
        ├── autoload_namespaces.php
        ├── autoload_psr4.php
        ├── autoload_real.php
        ├── autoload_static.php
        └── installed.json

3 directories, 12 files