Categories
PHP

Run Composer Commands Programmatically

Don’t you want to manage your dependencies programmatically?

Why do you need it?

There could be certain reasons. Some of these are the following.

  1. The most common reason; you don’t have access to the terminal and you want to manage your application’s dependencies programmatically.
  2. As a web developer, if you have worked with Laravel; you might have faced an issue that throws an error “Class [class name] not found”, But the class is there and you are using it correctly. The problem is your autoloader is not loading that class. Here you need to run composer dump-autoload in your project, the command will add all necessary classes to class mapping and whenever the next request comes in your project it will load that missing class along with other necessary classes.
  3. For some reason, you want to run composer update command to update your dependencies.
  4. You want to install/uninstall dependencies.

Let’s go to the solution. To run any shell command programmatically command Symfony gives us a component called Symfony/Process. And I have already written an article on how to use run composer command without installing it. Before going further I strongly recommend you to read it however you can still continue to the article.

Step:1 Manually download composer.phar file from here; And paste or upload it to your Laravel project’s root directory.

Now let’s assume you want to install a dependency phpseclib/phpseclib. To install that library your program should be like this.

<?php

namespace App\Http\Controllers;


use Symfony\Component\Process\Process;


class ProcessController extends Controller
{
    public function runComposerCommand()
    {

        $runningTasks = new Process(['php', 'composer.phar', 'require', 'phpseclib/phpseclib']);
        //setting laravel root dir in process so command will be executed in root dir
        $runningTasks->setWorkingDirectory(base_path());
        //setting timeout to unlimited because commands can take long time
        $runningTasks->setTimeout(0);
        //let's execute the command
        $runningTasks->run();
        dd($runningTasks->getOutput());
    }
}

Upon running the above script composer will install a dependency phpseclib/phpseclib into your project. And output might look like this. Mine is the following.

^ """

  \e[37;44m INFO \e[39;49m Discovering packages.  

  laravel/breeze \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m ▶
  laravel/sail \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e ▶
  laravel/sanctum \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39 ▶
  laravel/tinker \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m ▶
  nesbot/carbon \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\ ▶
  nunomaduro/collision \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m. ▶
  nunomaduro/termwind \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\ ▶
  spatie/laravel-ignition \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[9 ▶


  \e[37;44m INFO \e[39;49m No publishable resources for tag \e[1m[laravel-assets]\e[22m.  

"""

You can verify it by viewing your composer.json file. You will see a new entry "phpseclib/phpseclib": "^3.0" has been added to your require items.

Similarly, if you want to run dump-autoload command you program should look like this

<?php

namespace App\Http\Controllers;


use Symfony\Component\Process\Process;


class ProcessController extends Controller
{
    public function runComposerCommand()
    {

        $runningTasks = new Process(['php', 'composer.phar', 'dump-autoload']);
        //setting laravel root dir in process so command will be executed in root dir
        $runningTasks->setWorkingDirectory(base_path());
        //setting timeout to unlimited because commands can take long time
        $runningTasks->setTimeout(0);
        //let's execute the command
        $runningTasks->run();
        dd($runningTasks->getOutput());
    }
}

The output of the above program should look like this.

^ """
Generating optimized autoload files

  \e[37;44m INFO \e[39;49m Discovering packages.  

  laravel/breeze \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m ▶
  laravel/sail \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e ▶
  laravel/sanctum \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39 ▶
  laravel/tinker \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m ▶
  nesbot/carbon \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\ ▶
  nunomaduro/collision \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m. ▶
  nunomaduro/termwind \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\ ▶
  spatie/laravel-ignition \e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[90m.\e[39m\e[9 ▶

Generated optimized autoload files containing 5450 classes
"""

So you see how simple it was. Please comment if you like or if you have any questions.

Leave a Reply

Your email address will not be published. Required fields are marked *