How to get the root package path using composer
I'm developing a PHP component called php-app-config using composer.
This component, once required by another project, and installed using composer install
, should look for config files inside the config folder of the root package, something like root_package/config/config.yml
.
The ./config/config.yml
should exists only in the root package and not inside the component imported by the "require:" in composer.json
, as 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 can be a web app or command line utility. Is there any way to get the root package path using composer? If not, what is the better way?
Using ReflectionClass:
$reflection = new \ReflectionClass(\Composer\Autoload\ClassLoader::class);
$vendorDir = dirname(dirname($reflection->getFileName()));
You can use composer's very own \Composer\Factory::getComposerFile();
to get to the project root directory:
$projectRootPath = dirname(\Composer\Factory::getComposerFile());
And with your case, you can access your root-package/config/config.yml
by:
$configYmlPath = $projectRootPath . '/config/config.yml'
Don't forget to add composer
to your dependencies for the \Composer\Factory::class
to be available:
$ composer require composer/composer
-
I would suggest "anchoring" your application (web or cli) by defining the root path as a constant.
When you have for instance a
root-package/src/application.php
file, it should know where it lives, something likedefine('APP_ROOT_FOLDER', dirname(__DIR__));
could help. Once the constant is declared, it's available for dependencies, too.So, in
/php-app-config/Config.php
you would simply use the constant:$config = APP_ROOT_FOLDER . '/config/config.yml';
(Or define a
APP_CONFIG_ROOT_FOLDER
constant which points directly to the config folder of the application.) -
You could also try go some folder levels up from the dependency.
In
php-app-config/Config.php
you would use__DIR__
, which isroot-package/vendor/robotdance/php-app-config/src
. Now, you would need to go 4 levels up to reachroot-package/
.$config = __DIR__.'/../../../../config/config.yml';
This will not work out, when your application gets packaged as a PHAR.
Is there any way to get the root package path using Composer?
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');
then, go one folder up $config = dirname($vendorPath) . '/config/config.yml';