JAAulde February 2016

How can I provide a script for PHP CLI via composer (as standalone, and as dependency)

I am attempting to write a PHP script that I would like to run from the command line. I want to use composer to manage its dependencies, as well as to make it available to be installed as a dependency to other projects. I also want to maintain the ability to use it on its own (with its dependencies).

Currently, main.php is my "entry point" (what I would execute from the command line). As I built and tested it, I did so in the "stand alone" mindset. A such, main.php gets loads autoload like so:

<?php
require_once __DIR__.'/../vendor/autoload.php';

Continuing in stand alone mindset, I set it up like so:

  1. git clone package into place
  2. cd package
  3. composer install

This produces the following directory setup"

package
    |-composer.json
    |
    |-src
    |   |-ClassOne.php
    |   |
    |   |-ClassTwo.php
    |   |
    |   |-main.php
    |
    |-vendor
        |-autoload.php
        |
        |-composer
        |
        |-3rdpaty_1
        |
        |-3rdpaty_2

This works well--I can run php src/main.php which is able to find the classes it needs because it loads __DIR__.'../vendor/autoload.php'.

Where I run in to trouble is when I want to install the package as a dependency to another project (in order to have the script available to run there). I add my package to the composer.json and it gets installed. Attempting to run php vendor/compnay/package/src/main.php fails, however, because the necessary autoload.php is in a different place:

dependent_project
    |-composer.json
    |
    |-some_code
    |
    |-vendor
        |-autoload.php
        |
        |-composer
        |
        |-company
        |    |-package
        |        |-composer.json
        |        |
        |        |-src
           

Answers


Wouter J February 2016

A common practice is to look into both locations for an autoload file. See for instance this snippet used by Behat:

function includeIfExists($file)
{
    if (file_exists($file)) {
        return include $file;
    }
}
if ((!$loader = includeIfExists(__DIR__.'/../vendor/autoload.php')) && (!$loader = includeIfExists(__DIR__.'/../../../autoload.php'))) {
    fwrite(STDERR,
        'You must set up the project dependencies, run the following commands:'.PHP_EOL.
        'curl -s http://getcomposer.org/installer | php'.PHP_EOL.
        'php composer.phar install'.PHP_EOL
    );
    exit(1);
}

Post Status

Asked in February 2016
Viewed 2,894 times
Voted 14
Answered 1 times

Search




Leave an answer