Get filesystem path of installed composer package

后端 未结 4 1042
渐次进展
渐次进展 2021-02-08 07:43

How can get filesystem path of composer package?

composer.json example:

{

    \"require\" : {
        \"codeception/codeception\" : \"@stable\",
                


        
相关标签:
4条回答
  • 2021-02-08 08:02

    Try ReflectionClass::getFileName - Gets the filename of the file in which the class has been defined. http://www.php.net/manual/en/reflectionclass.getfilename.php

    Example:

    $reflector = new ReflectionClass("\Geocoder\HttpAdapter\HttpAdapterInterface");
    echo $reflector->getFileName();
    

    Or you may use this:

    $loader = require './vendor/autoload.php';
    echo $loader->findFile("\Geocoder\HttpAdapter\HttpAdapterInterface");
    

    The first method try to load class and return loaded class path. The second method return path from composer database without class autoload.

    0 讨论(0)
  • 2021-02-08 08:17

    Here is my solution to get the vendor path without using the $composer object :

    <?php
    
    namespace MyPackage;
    
    use Composer\Autoload\ClassLoader;
    
    class MyClass
    {
        private function getVendorPath()
        {
            $reflector = new \ReflectionClass(ClassLoader::class);
            $vendorPath = preg_replace('/^(.*)\/composer\/ClassLoader\.php$/', '$1', $reflector->getFileName() );
            if($vendorPath && is_dir($vendorPath)) {
                return $vendorPath . '/';
            }
            throw new \RuntimeException('Unable to detect vendor path.');
        }
    }
    
    0 讨论(0)
  • 2021-02-08 08:17

    Not sure if the following is the correct way for this because composer is changing so fast.

    If you run this command:

    php /path/to/composer.phar dump-autoload -o
    

    it will create a classmap array in this file

    vender/composer/autoload_classmap.php
    

    with this format "classname" => filepath.

    So to find filepath of a given class is simple. If you create the script in your project's root folder, you can do this:

    $classmap = require('vender/composer/autoload_classmap.php');
    $filepath = $classmap[$classname]?: null;
    
    0 讨论(0)
  • 2021-02-08 08:21

    All of this is based on the assumption that you are actually talking about packages and not classes (which are mentioned in the example but are not asked for in the question).

    If you have the Composer object, you can get the path of the vendor directory from the Config object:

        $vendorPath = $composer->getConfig()->get('vendor-dir');
    

    $vendorPath should now contain /home/me/public_html/vendor/.

    It shouldn't be too hard to construct the rest of the path from there, as you already have the package name.

    If this feels too flaky or you don't want to write the logic, there is another solution. You could fetch all packages, iterate until you find the right package and grab the path from it:

        $repositoryManager = $composer->getRepositoryManager();
        $installationManager = $composer->getInstallationManager();
        $localRepository = $repositoryManager->getLocalRepository();
    
        $packages = $localRepository->getPackages();
        foreach ($packages as $package) {
            if ($package->getName() === 'willdurand/geocoder') {
                $installPath = $installationManager->getInstallPath($package);
                break;
            }
        }
    

    $installPath should now contain /home/me/public_html/vendor/willdurand/geocoder

    0 讨论(0)
提交回复
热议问题