How to get the root package path using composer

I am developing a PHP component called php-app-config using composer . This component, which is required by another project and installed using composer install , should look for configuration files inside the config folder of the root package , something like root_package/config/config.yml .

./config/config.yml should exist only in the root package, and not inside the component imported "require:" in composer.json , as shown below:

 ▾ root-package/ ▸ bin/ ▸ build/ ▾ config/ ▸ locales/ config.yml ▸ src/ ▸ tests/ ▾ vendor/ ▸ composer/ ▸ phpdocumentor/ ▸ phpspec/ ▸ phpunit/ ▾ robotdance/ ▾ php-app-config/ ▾ src/ Config.php -> how to get the root "config/config.yml" path from here? ▸ tests/ composer.json composer.lock phpunit.xml README.md 

The root package may be a utility for web applications or a command line. Is there a way to get the root package path using composer? If not, which way is better?

+5
source share
3 answers
  • I would suggest binding your application (web or cli), specifying the root path as a constant.

    If you have the root-package/src/application.php file, it should know where it lives, something like define('APP_ROOT_FOLDER', dirname(__DIR__)); may I help. Once a constant is declared, it is also available for dependencies.

    So in /php-app-config/Config.php you just use the constant:

    $config = APP_ROOT_FOLDER . '/config/config.yml';

    (or define the constant APP_CONFIG_ROOT_FOLDER , which points directly to the application configuration folder.)

  • You can also try moving some folder levels from dependency.

    In php-app-config/Config.php you should use __DIR__ , which is equal to root-package/vendor/robotdance/php-app-config/src . Now you need to go through 4 levels to reach root-package/ .

    $config = __DIR__.'/../../../../config/config.yml';

    This will not work when your application is packaged as a PHAR.


Is there a way to get the root package path using Composer?

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

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

then go to one folder up $config = dirname($vendorPath) . '/config/config.yml'; $config = dirname($vendorPath) . '/config/config.yml';

+2
source

Using ReflectionClass:

 $reflection = new \ReflectionClass(\Composer\Autoload\ClassLoader::class); $vendorDir = dirname(dirname($reflection->getFileName())); 

But if you need to know the provider directory that requires autoload.php , then you can check for the existence of the ClassLoader class:

 if (!class_exists('\Composer\Autoload\ClassLoader')) { require 'vendor/autoload.php'; } 
+1
source

You can use composer very own \Composer\Factory::getComposerFile(); to get to the project root directory:

$projectRootPath = dirname(\Composer\Factory::getComposerFile());

And in your case, you can access your root-package/config/config.yml with:

$configYmlPath = $projectRootPath . '/config/config.yml'

Remember to add composer to your dependencies for \Composer\Factory::class , which will be available:

$ composer require composer/composer

+1
source

All Articles