AspectMock
AspectMock copied to clipboard
Parent class not found by locator
When using custom autoloader and try to get an instance of a class which has parent or implements an interface form the same custom namespace I have an error "PHP Fatal error: Uncaught InvalidArgumentException: Class [parent class name] was not found by locator in /workspace/projects/test/vendor/goaop/parser-reflection/src/ReflectionEngine.php:112".
I have very simple setup:
<?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;
}
}
Class B is loaded via my custom autoloader, but then the locator tries to load parent class A via composer autoloader and returns this error. Is this a bug, or I'm doing something wrong?
I am also seeing this error. It appears it is the goasp
framework's Go\ParserReflection\ReflectionEngine::$locator
that causes the issue. I don't see where AspectMock touches the engine which is bootstrapped to use the Go\ParserReflection\Locator\ComposerLocator
.
I'm currently trying to correct the issue by calling ReflectionEngine::init
with a combination of FilterInjectorTransformer
but haven't found the key yet.
I've had limited success with having a Locator that autoloads the class then and uses \ReflectionClass
to report what file it is loaded from. I am eventually getting a segfault/xdebug nesting limit however.
<?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
// set the autoloading Locator
\Go\ParserReflection\ReflectionEngine::init(new lib\AutoLoadingLocator());
$b = new \lib\B();
Class \lib\AutoLoadingLocator:
namespace lib;
class AutoLoadingLocator implements \Go\ParserReflection\LocatorInterface {
public function locateClass($className) {
return (new ReflectionClass($className))->getFileName();
}
}
Hi, guys! In order to use custom autoloader you should re-init ReflectionEngine
with composite class locator that will be able to locate your classes or you can use CallableLocator with closure for resolving paths.
Or, even better you could switch your code base to the PSR0/PSR-4 :+1:
Thank you both for the responses. I'm using Yii2 framework for my project so I added psr-0 autoloader in composer and fixed the issue, but since I didn't saw it in the examples I wasn't sure if this is the right way to do it. Maybe it's good idea to update examples.
Thank you for the verification. We won't be able to change our codebase to PSR-0/4 but I could modify our autoloaders to expose the path resolving and see if that resolves the segfaulting from relying on \Reflection
.
I believe the segfault I was seeing is actually around https://github.com/goaop/parser-reflection/issues/43. Will update that project with any new issues.
Getting into an inf loop with a class like this:
class Foo {
const MINUTE = 60;
const HOUR = 3600;
const DEFAULT = self::MINUTE;
}
Hi, guys! In order to use custom autoloader you should re-init ReflectionEngine with composite class locator that will be able to locate your classes or you can use CallableLocator with closure for resolving paths.
hi @lisachenko could you point to or provide an example for this?
I have some locator issues using a facade class which calls classes using a variable
@kzap i had the exact same issue getting AspectMock to work while using classes in the root namespace.
Think of the following structure i had
<?php
class dataobject {}
<?php
namespace fubar;
class A extends \dataobject {}
I got the same error that the class dataobject
could not be located.
The locator looked into the classmap of composer and couldn't find the class.
After i moved dataobject
into a namespace (e.g. fu\dataobject
) everything worked as intended.
@icanhazstring Yes thats what I did, put everything inside a Namespace and it worked :)
Sorry for playing an archeologist but I recently ecnountered similar problem. The difference is that I use no custom autoloader and everything is inside namespaces. But if I extend my classes or implement my interfaces it throws exact same errors
Class app\controllers\BaseController was not found by locator
Class app\models\MyInterface was not found by locator
I would appreciate any input cause im running out of ideas.