Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AutoloadSourceLocator uses the wrong directory #384

Closed
oqq opened this issue Nov 24, 2017 · 2 comments · Fixed by #437
Closed

AutoloadSourceLocator uses the wrong directory #384

oqq opened this issue Nov 24, 2017 · 2 comments · Fixed by #437
Assignees
Milestone

Comments

@oqq
Copy link

oqq commented Nov 24, 2017

Hi!

In another library using this package an issue appeared which arises from here.
prooph/message-flow-analyzer#2

After some investigation i can summarize it to below facts.

Given my vendor directory, fulfilled from composer, has two packages with the same namespace, but different directories in which the code lies by using PSR-4.
e.g.

  • zendframework/zend-expressive-router
  • zendframework/zend-expressive-fastroute

And i use composers autoloader and he reckons to uses first the fastroute package and router afterwards. (Was the case in the linked issue)

Than this call

use Roave\BetterReflection\Reflection\ReflectionClass;
$reflection = ReflectionClass::createFromName(\Zend\Expressive\Router\RouterInterface::class);

would raise this exception:

PHP Fatal error:  Uncaught Roave\BetterReflection\Reflector\Exception\IdentifierNotFound: Roave\BetterReflection\Reflection\ReflectionClass "Zend\Expressive\Router\RouterInterface" could not be found in the located source 

The method attemptAutoloadForIdentifier returns this file path:

vendor/composer/../zendframework/zend-expressive-fastroute/src/RouterInterface.php

which is properly wrong and should be:

vendor/composer/../zendframework/zend-expressive-router/src/RouterInterface.php

This only happens if the $prefixDirsPsr4 array from vendor/composer/autoload_static.php contains a like this:

        'Zend\\Expressive\\Router\\' => 
        array (
            0 => __DIR__ . '/..' . '/zendframework/zend-expressive-fastroute/src',
            1 => __DIR__ . '/..' . '/zendframework/zend-expressive-router/src',
        ),

But not if the router is the first value in that array.

Perhaps this is an issue from composer, but since the nativ reflection from php under same circumstances works like a charm, I would drop it here. sorry ;)

$reflection = new \ReflectionClass(\Zend\Expressive\Router\RouterInterface::class);
echo $reflection->getFileName(); #vendor/zendframework/zend-expressive-router/src/RouterInterface.php

Thanks!

@asgrim
Copy link
Member

asgrim commented Nov 24, 2017

Interesting find; that kinda makes sense; when we hijack the file stream in

self::$autoloadLocatedFile = $path;
we don't actually check the file exists and is valid. Would be fairly simple to implement that tho, I'd think.

@Ocramius
Copy link
Member

Just adding some spice here (for anyone willing to write test cases): file might be valid and readable, but it may not contain the class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants