Codeception / AspectMock定位器找不到父类

时间:2016-12-05 12:15:54

标签: php

我遇到Codeception/AspectMock的问题。 当使用自定义自动加载器并尝试创建一个类的实例,该类具有相同的自定义命名空间的父类时,我有这样的错误:

  

PHP致命错误:未捕获InvalidArgumentException:类[parent   定位器未找到类名]   供应商/ goaop /解析器反射/ SRC / ReflectionEngine.php:112

我的设置非常简单:

<?php

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

$kernel = AspectMock\Kernel::getInstance();
$kernel->init([
    'debug' => true,
    'includePaths' => [__DIR__. '/lib'],
]);
$kernel->loadFile(__DIR__ . '/autoload.php'); // custom autoloader

$b = new \lib\B();

Class \ lib \ B:

namespace lib;

class B extends A {}

Class \ lib \ A:

namespace lib;

class A
{
    public function getName()
    {
        return static::class;
    }
}

通过我的自定义自动加载器加载B类,但是定位器尝试通过composer autoloader加载父类A并返回此错误。这是一个错误,还是我做错了什么?

2 个答案:

答案 0 :(得分:4)

主题入门者已经获得答案on GitHub

  

要使用自定义自动加载器,您应该使用复合类定位器重新初始化ReflectionEngine,该复合类定位器将能够找到您的类,或者您可以将CallableLocator与闭包一起使用来解析路径。

     

或者,甚至更好的是,您可以将代码库切换到PSR0 / PSR-4

例如:

$kernel->loadFile(__DIR__ . '/autoload.php'); // custom autoloader

\Go\ParserReflection\ReflectionEngine::init(
    new class implements \Go\ParserReflection\LocatorInterface {
        public function locateClass($className) {
            return (new ReflectionClass($className))->getFileName();
        }
     }
);

$b = new \lib\B(); // here you go

答案 1 :(得分:1)

如果您可以轻松地在代码库上进行查找和替换,也许您可​​以将代码重构为PSR-4自动加载标准,而完全不需要自定义自动加载器。

这是规范https://www.php-fig.org/psr/psr-4/。我将尽力解释它。

想象一下将小写的命名空间objects_to_remove <- c("age", "another_object") # etc rm(list = objects_to_remove) 更改为lib,并将该命名空间设置为Lib中的src/目录:

composer.json

设置后,运行"autoload": { "psr-4": { "Lib\\": "src/" } } 。然后,您要做的就是搜索并替换composer dumpautoload,并替换为namespace lib;

位于namespace Lib;中的示例类的顶部应该是src/Form.php,然后是namespace Lib;

class Form

命名空间使用文件夹命名约定。直接在<?php namepace Lib; class Form { // code } 中的所有类都具有命名空间src/。如果存在子目录,则目录名称将成为名称空间的一部分。例如,Lib;中的文件将具有src/Form/Field/Text.php

namespace Lib\Form\Field; class Text {}

您可以在上面的链接中看到完整的约定,但一般规则是使所有文件夹都以大写字母开头,例如您的类名,并且自动加载器应能够找到所有类。

这可能是您的最佳实践解决方案,就像我说的那样,只需要一点文件重命名和名称空间调整即可。祝你好运!