Last active
February 10, 2021 10:41
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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(); | |
} | |
} |
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.
Tested this with a vanilla php application calling a Lumen application and seems to work quite nicely. Thanks :-)
@simonhamp Thank you very much. This works perfectly
@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
For when you want/need to call a specific (local) Laravel/Lumen app's
artisan
command directly from another Laravel/Lumen application. (Of course, if youcomposer require
the Symfony Process Component, Illuminate Support and PHP DotEnv you can use this from any PHP application to call a local artisan in another app.)I had to create this a few weeks ago because I couldn't find any other way to do this and I finally had reason to pull it out into its own class for reuse, so I thought it was worth sharing.
It mimics the
Artisan
facade, providing acall
static method. It's differences are that it needs the path to the application you're trying to run an artisan command against and optionally a path to the appropriate PHP binary to use (in case the default doesn't work for you for some reason).I know it's quite rare that you'd ever really need this and I'm sure there must be a nicer solution out there that I'm missing, so I'd welcome comments, feedback and suggestions!