0

is it possible to run composer or git commands from within a controller in Laravel? Something like that:

class TestController extends Controller
{
    //
    public function shell(Request $request){
        if($request->isMethod('post')){


            $data['output'] = shell_exec('composer update');
            // or some git commands
            return view('tests.shell', $data);
        } else {
            return view('tests.shell');
        }
    }
}

If I do it the way shown above, I get no message. I think, the problem is, that these commands have to be run in the projects root directory and not in an subfolder.

And is there a php function to run a complete shell script and not only single commands?

I have tested this:

echo shell_exec('php ' . __DIR__ . '/../shell.php');
// shell.php is in projects root directory

The script is executed, but not in the root directory.

Thanks!

2 Answers 2

10

I haven't noticed it before, but Laravel ships with a tool to run terminal commands/composer commands. You can use the The Process Component from Symfony. So it becomes very easy to run commands.

An example for Laravel 5.2:

namespace App\Http\Controllers;

use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;

use App\Http\Requests;

use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;

class SetupController extends Controller
{
    public function setup(){
        $migration = new Process("php artisan migrate");

        $migration->setWorkingDirectory(base_path());

        $migration->run();

        if($migration->isSuccessful()){
            //...
        } else {
            throw new ProcessFailedException($migration);
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

You can try something like this:

$data['output'] = shell_exec( '(cd '. base_path() .' && /usr/local/bin/composer info)' );

// debug
dd( $data );

The command is in ( and ) so that we mode to the root folder if the project and the execute composer info.

The following git command also works too, but not git pull or git fetch:

$data['output'] = shell_exec( '(cd '. base_path() .' && /usr/bin/git status)' )

I've also tried the /usr/local/bin/composer update command, but as you have to wait for the packages to update the script either returns null or times out.

Its also worth pointing out that the full path to composer / git should be used, i.e. /usr/local/bin/composer or you will always see null returned.

For your PHP script, try something similar to:

echo shell_exec('(cd '. base_path() .' && php shell.php)');

EDIT

If you want to log the output of the command to file and attempt to capture in PHP, you can try:

$data['output'] = shell_exec( '(cd '. base_path() .' && /usr/bin/git status | tee -a file.log)' )

The tee -a file.log part will save output to file.log as well as output to screen (so shell_exec can pickup output), and the -a flag will append new output to the file if it already exists (useful if you want to have one log file with historical record of previous commands).

5 Comments

Everything works fine in my local environment. But I have no success in my laravel installation. The result is NULL. I also have tried to execute other commands than composer / git (e.g. php artisan make:controller XyzController) but with no success...
I've had mixed results too. Some commands work perfectly, while others return null. Could be related to the type of output generated by the command or PHP timing out...
Do you know a way to log the actions? It's difficult to check if an command succeeded or not when there is no output^^
I've started a diskussion on laracasts.com. I will try this later and will give you a feedback if you want.
If you want to log the output you can do $data['output'] = shell_exec( '(cd '. base_path() .' && /usr/bin/git status | tee -a file.log)' ). The tee -a file.log will save output to file.log as well as output to screen, and the -a flag will append new output to the file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.