自定义自动加载与Composer的自动加载有冲突吗?

时间:2019-07-26 16:42:56

标签: php composer-php phpunit autoload spl-autoload-register

我有一个PHP项目,该文件加载了名为custom_funcs.php的引导文件,该文件位于根Web目录中。该文件包含一堆函数,定义了几个常量,并执行以下操作:

    require dirname( __DIR__ ) . '/lib/php/vendor/autoload.php';
    spl_autoload_register( function ($class_name) { include __DIR__ ."/classes/$class_name.php"; });
    set_include_path( get_include_path() . PATH_SEPARATOR . SITEROOT );

第一行加载Composer自动加载器。 (请注意,编写器库位于根Web目录外部)。第二行告诉我的代码在哪里寻找无法识别的类,这样我就不必不断手动加载我曾经使用过的类文件。第三行将Web根目录添加到PHP的PATH。

几年来,它与几个Composer软件包一起运行都很好。

然后...我安装了PhpUnit。总的来说,除了运行测试时,我一切正常,

  1. 如果没有错误,则可以正常工作。
  2. 如果出现错误,我还会收到PHP警告:
Warning: include(C:\...path_to_web_root.../classes/SebastianBergmann\Invoker\Invoker.php): failed to open stream: No such file or directory in C:\...path_to_web_root...\common_funcs.php on line 14
Warning: include(): Failed opening 'C:\...path_to_web_root.../classes/SebastianBergmann\Invoker\Invoker.php' for inclusion (include_path='xxxxxxx') in C:\...path_to_web_root...\common_funcs.php on line 14

因此PhpUnit试图自动加载名为“ Invoker”的类,但是代码使用的是我自己的spl_autoload_register设置的自动加载路径。

是否可以解决此问题?这是PhpUnit中的错误吗?

我可以通过在包含行之前使用“ @”来隐藏错误,但我会尽一切努力避免@hide错误

注意:在通过以下方式进行测试之前,我正在加载custom_funcs.php

    public static function setUpBeforeClass(): void {
        require 'common_funcs.php';
    }

文件结构可能会使其更清晰:

c:/some_path/
..lib/
....php/
......vendor/
........(third-party Composer libraries)
..webroot/
....custom_funcs.php
....classes/
......(namespace)/
........(my custom classes)

2 个答案:

答案 0 :(得分:0)

最简单的方法是修复自动加载器-如果自动加载器无法加载类,则自动加载器不应引发此类错误。在这种情况下,什么都不做是正确的操作:

spl_autoload_register(function ($class_name) {
    if (file_exists(__DIR__ . "/classes/$class_name.php")) {
        include __DIR__ . "/classes/$class_name.php";
        return true;
    }
});

答案 1 :(得分:0)

您也许可以用composer.json中的classmap autoloader替换自定义自动加载器功能:

{
    "autoload": {
        "classmap": ["classes/"],
        "files": ["custom_funcs.php"]
    }
}
  

通过扫描给定目录/文件中所有.php.inc文件中的类来构建此映射。

每当创建一个新类时,您可能都必须使用composer dump-autoload来更新作曲家的自动加载器,以使其能够被拾取。我不确定是默认情况还是仅在优化自动加载器时才是这种情况。在任何情况下,都可以通过对新类采用PSR-0或PSR-4命名约定来解决。

edit:由于将使用作曲家的自动加载器为您自动加载所有文件,因此不再需要手动require对其进行加载。因此,您也可以删除setupBeforeClass方法