Skip to content

Instantly share code, notes, and snippets.

@simonhamp
Last active February 10, 2021 10:41
Show Gist options
  • Save simonhamp/b3e628adcedc0af4ffdf5ae59e9fb6a3 to your computer and use it in GitHub Desktop.
Save simonhamp/b3e628adcedc0af4ffdf5ae59e9fb6a3 to your computer and use it in GitHub Desktop.
RemoteArtisan: A way to call another Laravel/Lumen application's artisan command from the context of the current application.
<?php
namespace App;
use Dotenv\Dotenv;
use Illuminate\Support\Str;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
class RemoteArtisan
{
/**
* Implements an interface similar to Artisan::call.
*
* @param string $path The full path to the remote application's root
* @param string $command The Artisan command to run, e.g. 'vendor:publish'
* @param array $parameters The parameters to pass to the artisan command
* @param string $php The path to the PHP executable
* @return mixed
* @throws ProcessFailedException
*/
public static function call($path, $command, $parameters = [], $php = null)
{
// Prepare parameters for appending
$options = '';
foreach ($parameters as $name => $value) {
$value = '"'.$value.'"';
if (is_int($name)) {
$options .= " $value";
} else {
$value = ($value !== true ? "=$value" : '');
$options .= " {$name}{$value}";
}
}
// Swap out the full path to the current PHP executable binary
if (! $php) {
$php = PHP_BINDIR . '/php';
}
// Load .env for the target app
$env = new Dotenv($path);
$env->overload();
// Append the artisan command to the path
$artisan = Str::finish($path, '/').'artisan';
// Build up the final command
$command = "{$php} {$artisan} {$command}{$options}";
// Run the command in its environment
$process = new Process($command, $path);
$process->run();
// Restore original environment
$env = new Dotenv(base_path());
$env->overload();
// If there was no response
if (! $process->isSuccessful()) {
throw new ProcessFailedException($process);
}
return $process->getOutput();
}
}
@simonhamp
Copy link
Author

simonhamp commented Dec 22, 2017

Simple usage example, from app located at /www/laravel-todo-app/ calling /www/laravel-invoice-app/:

<?php

use App\RemoteArtisan;

// For example, in an event handler when a Todo is completed...
RemoteArtisan::call('/www/laravel-invoice-app/', 'make:invoice', ['INV-0001', '[email protected]', '--send' => true]);

Of course, this assumes that the laravel-invoice-app defines and registers an Artisan command with the signature make:invoice and appropriate options.

@toxicchili
Copy link

Tested this with a vanilla php application calling a Lumen application and seems to work quite nicely. Thanks :-)

@kakposoe
Copy link

@simonhamp Thank you very much. This works perfectly

@simonhamp
Copy link
Author

@toxicchili @kakposoe glad that you've found this useful :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment