12
Apr
2016

Easily Running Custom Scripts in a Bootstrapped Laravel Environment

Laravel is pretty great. It conveniently includes a very robust command line tool, artisan, that can very easily be extended with custom commands.

That's great and meets most needs, but what if you want to just run an arbitrary script inside your bootstrapped laravel environment without having to create a specific artisan command to do so?

If you find yourself needing or wanting to do this, I have a solution for you that keeps things pretty simple, the way working with laravel tends to be.

So the easiest solution is to add a custom artisan command that allows you to load/run arbitrary scripts within the bootstrapped environment that artisan provides.

<?php namespace App\Console\Commands;

use Illuminate\Console\Command;

class Script extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'script 
                            {filename : path/filename.php of script to run relative to project root} 
                            {args?* : Optional args to pass to script}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Runs a script inside a bootstrapped laravel environment.';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        // Make $args (if any) available to the file being included
        $args = $this->argument('args');

        // include the script file to run
        require($this->argument('filename'));
    }
}

So what that will do is provide a custom script command that will accept a filename and optionally an unlimited number of arguments.

As such, if I had a very simple script like the following, running php artisan script filename.php App\\User App\\Task will loop through and vardump the results of the select * queries against those models' database tables.

<?php

foreach ($args as $arg) {
    var_dump($arg::all()->toArray());
}

Obviously that example is really basic.  But it should give you an idea of what you can do.  If you wanted classes in that script, no problem, just include a line outside the class that instantiates an object and calls whatever methods are necessary. The file, when loaded, will automatically execute procedural code in the file. That code, by the way, has access to all those args you passed on the command line as an array $args.

Easy peasy.. just the way the rest of laravel is.

EDIT: As pointed out by Dan Sandberg in the comments below, to make this command available you must add it to the protected $commands array within the Kernel.php file.