Streaming Command Output To The Browser

Following on from my last post about output buffer streaming I wondered if it was possible to stream the output from a Laravel Artisan command to the browser.

You might be asking "but why?" good question! The answer is simply because I wanted to know if you could.

Spoiler Alert: You can and it's easy

After spelunking though the Laravel/Symphony command handling code for a while I discovered that most of the code to do this is already written. Symphony includes a StreamOutput class and the Artisan::call() method accepts a custom output buffer class.

All I needed to do hook it up to the php://output stream:

$outputBuffer = new class extends \Symfony\Component\Console\Output\StreamOutput
{
    public function __construct()
    {
        parent::__construct(fopen('php://output', 'w'));
    }
};

Artisan::call('command:name', outputBuffer: $outputBuffer);

Note the anonymous class is not required, it can be a regular class

While this works it isn't very readable because the output contains \n rather than <br>. We can convert these on the fly like this:

$outputBuffer = new class extends \Symfony\Component\Console\Output\StreamOutput
{
    public function __construct()
    {
        parent::__construct(fopen('php://output', 'w'));
    }

    protected function doWrite(string $message, bool $newline)
    {
        $message = str_replace("\n", '<br>', $message);

        if ($newline) {
            $message .= '<br>';
        }

        parent::doWrite($message, false);
    }
};

Popular Reads

Subscribe

Keep up to date

Please provide your email address
Please provide your name
Please provide your name
No thanks