cenob8
cenob8

Reputation: 634

Get response from Artisan call

When I run in terminal php artisan migrate this results in 'Nothing to migrate' when indeed there is nothing to migrate.

When I use Artisan::call('migrate') in code (use this in a custom Artisan command) this doesn't return any message. It just executes the code without any feedback.

If I vardump() the result of the Artisan::call method it just returns an int(0)

Is it possible to get the response of the Artisan call method?

Upvotes: 19

Views: 19223

Answers (7)

Eduardo
Eduardo

Reputation: 1831

Maybe this will save some time to someone in the future, for me worked a mix of 2 answers:

use Symfony\Component\Console\Output\StreamOutput;

$stream = fopen("php://output", "w");
Artisan::call('migrate', [
    '--path' => 'database/migrations/customer',
    '--force' => true,
    '--database' => $connectionName
], new StreamOutput($stream));

$callResponse = ob_get_clean();

StreamOutput helps to put the response in buffer and ob functions to get the response.

Upvotes: 1

mfink
mfink

Reputation: 1380

When the Artisan command output you want is issuing an echo.

You can access this type of output with ob_start and ob_get_clean.

For example, if your command echos JSON.

Artisan::command('myecho:command', function () {

    echo json_encode(config('myconfig'), true);

})->describe('outputs json');

Then you can access the JSON output by wrapping the command call in a buffer:

\ob_start();
\Artisan::call('myecho:command');
$output = \ob_get_clean();

var_dump($output);

Upvotes: 1

aimme
aimme

Reputation: 6773

Late but might be of use to someone searching for the use case.

Let me add how i did it in my tests to print the results to console. my problem was printing output while tests are running migrations. i was using modules and wanted to see the results of the migration process.

$this->artisan('module:migrate');
//same as running php artisan module:migrate or
// $this->app['Illuminate\Contracts\Console\Kernel']->call('module:migrate');

echo $this->app['Illuminate\Contracts\Console\Kernel']->output();

Upvotes: 2

PiTheNumber
PiTheNumber

Reputation: 23542

For me with Laravel 5.1 all this did not work but you can simply use:

Artisan::output()

Upvotes: 24

bishop
bishop

Reputation: 39414

Yes, it's possible. To get the output of a built-in artisan command from inside a custom command, pass the OutputStream from your command into the Artisan::call. Example:

class MyCommand extends \Illuminate\Console\Command
{
    public function fire()
    {
        \Artisan::call('optimize', [], $this->getOutput());
    }
}

Upvotes: 8

handlebar_
handlebar_

Reputation: 441

I'm able to get the output of Artisan::call() with the via the following:

use Symfony\Component\Console\Output\StreamOutput;

$stream = fopen("php://output", "w");
Artisan::call("migrate", array(), new StreamOutput($stream));

var_dump($stream);

Upvotes: 13

Jeff Lambert
Jeff Lambert

Reputation: 24661

The return result of all commands is defined in the class Symfony\Component\Console\Command\Command, method run:

return is_numeric($statusCode) ? (int) $statusCode : 0;

The $statusCode variable is set by calling the command's execute method, which in artisan's case is defined in the class Illuminate\Console\Command:

protected function execute(InputInterface $input, OutputInterface $output)
{
    return $this->fire();
}

The result of the fire method is left up to the individual commands, in the case of php artisan migrate command, nothing is returned from the method so the $statusCode is null (which is why you get the 0 returned from Symfony\Component\Console\Command\Command::run method)

If you want to get a response back from a custom command, just return an integer back from your fire method and it will bubble back up into the $statusCode. You can use that to programmatically switch against different results of your custom command.

If you specifically want to get the result from the artisan:migrate command, then I don't think there's much you can do to change the return value besides wrapping the command in your own custom command that calls it.

Upvotes: 9

Related Questions