Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 832
Menegazzo Avatar asked Jun 20 '16 14:06

Menegazzo


People also ask

How do I find the composer path?

Installation - Windows# This is the easiest way to get Composer set up on your machine. Download and run Composer-Setup.exe. It will install the latest Composer version and set up your PATH so that you can call composer from any directory in your command line. Note: Close your current terminal.

What is composer package?

Package# Composer is a dependency manager. It installs packages locally. A package is essentially a directory containing something. In this case it is PHP code, but in theory it could be anything.

Where does composer global install?

This will install PHPUnit and all its dependencies into the ~/. composer/vendor/ directory and, most importantly, the phpunit CLI tools are installed into ~/. composer/vendor/bin/.


3 Answers

Using ReflectionClass:

$reflection = new \ReflectionClass(\Composer\Autoload\ClassLoader::class);
$vendorDir = dirname(dirname($reflection->getFileName()));
like image 147
Andrey Izman Avatar answered Oct 22 '22 13:10

Andrey Izman


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

like image 43
Jim M Avatar answered Oct 22 '22 13:10

Jim M


  • 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 like define('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 is root-package/vendor/robotdance/php-app-config/src. Now, you would need to go 4 levels up to reach root-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';

like image 3
Jens A. Koch Avatar answered Oct 22 '22 13:10

Jens A. Koch