How to Make a Laravel Artisan Command to Install the application

QADIR PERVEZ
4 min readMar 17, 2022
php artisan app:install

Today, we’ll look at how to make a custom artisan command that would install a Laravel application in one step. Wouldn’t it be great if you can share a Laravel project with your coworkers and they can set it up with a single command?

Laravel comes with Artisan, a sophisticated command-line interface that may help you develop your application. We will use Artisan to create a custom command for our application.

Let’s begin by creating a new Laravel application. If you have already installed Laravel installer, you can write in your terminal.

laravel new install-command

Or via Composer create-project.

composer create-project laravel/laravel install-command

Now, create an Artisan command inside your project directory.

php artisan make:command AppInstaller

This command will create an AppInstaller class in your App\Console\Commands namespace

your AppInstaller.php file will look like this:

We’ll now update the command signature.

protected $signature = 'app:install                        {--db-host=localhost : Database Host}                        {--db-port=3306 : Port for the database}                        {--db-database= : Name for the database}                        {--db-username=root : Username for accessing the database}                        {--db-password= : Password for accessing the database}                        ';

basically, we have created a command with some options for configuring the database.

The command description will now be changed into:

protected $description = ‘To install the application via CLI’;

we will add several functions that will be used in our handle method.

Because our operation is simple and we have used some default arguments above, the only option that is necessary is DB_DATABASE because DB_USERNAME is root, DB_HOST is localhost, DB_PORT is 3306 and DB_PASSWORD may be an empty string by default.

public function missingRequiredOptions(){    return !$this->option('db-database');}

We’ll use this function to update our .env file, as the name implies.

public static function updateEnv($data){     $env = file_get_contents(base_path('.env'));     $env = explode("\n", $env);     foreach ($data as $dataKey => $dataValue) {          $alreadyExistInEnv = false;          foreach ($env as $envKey => $envValue) {               $entry = explode('=', $envValue, 2);               // Check if exists or not in env file               if ($entry[0] == $dataKey) {                     $env[$envKey] = $dataKey . '=' . $dataValue;                     $alreadyExistInEnv = true;               } else {                     $env[$envKey] = $envValue;               }         }         // add the variable if not exists in env        if (!$alreadyExistInEnv) {            $env[] = $dataKey . '=' . $dataValue;        }   }   $env = implode("\n", $env);   file_put_contents(base_path('.env'), $env);   return true;}

This function will be used to copy the .env.example file to the .env file.

public static function copyEnvExampleToEnv(){     if (!is_file(base_path('.env')) &&       is_file(base_path('.env.example'))) {          File::copy(base_path('.env.example'), base_path('.env'));      }}

to generate the APP_KEY.

public static function generateAppKey(){     Artisan::call('key:generate');}

to run migrations and seeders.

public static function runMigrationsWithSeeders(){     try {          Artisan::call('migrate:fresh', ['--force' => true]);          Artisan::call('db:seed', ['--force' => true]);     } catch (\Exception $e) {          return false;     }     return true;}

Finally, from the given command options, change the .env file.

public function updateEnvVariablesFromOptions(){     $this->updateEnv([          'DB_HOST' => $this->option('db-host'),          'DB_PORT' => $this->option('db-port'),          'DB_DATABASE' => $this->option('db-database'),          'DB_USERNAME' => $this->option('db-username'),          'DB_PASSWORD' => $this->option('db-password'),     ]);     $conn = config('database.default', 'mysql');     $dbConfig = Config::get("database.connections.$conn");
$dbConfig['host'] = $this->option('db-host');
$dbConfig['port'] = $this->option('db-port'); $dbConfig['database'] = $this->option('db-database'); $dbConfig['username'] = $this->option('db-username'); $dbConfig['password'] = $this->option('db-password');
Config::set("database.connections.$conn", $dbConfig);
DB::purge($conn); DB::reconnect($conn);}

and in our handle method.

public function handle(){     if ($this->missingRequiredOptions()) {          $this->error('Missing required options');          $this->line('please run');          $this->line('php artisan app:install --help');          $this->line('to see the command usage.');          return 0;     }
$this->alert('Application is installing...');
static::copyEnvExampleToEnv(); $this->generateAppKey();
$this->updateEnvVariablesFromOptions(); $this->info('Env file created successfully.');
$this->info('Runnning migrations and seeders...'); if (!static::runMigrationsWithSeeders()) { $this->error('Your database credentials are wrong!'); return 0; } $this->alert('Application is installed successfully.'); return 1}

We begin by copying .env.example to the .env file, then generate APP_KEY, update the .env file using the options specified while running the command, and then run migrations and seeders.

This is how your AppInstaller.php file should now appear.

now for running the Artisan Command in your terminal use the given command below.

php artisan app:install --db-database=YOUR_DB_NAME --db-username=YOUR_DB_USERNAME --db-password=YOUR_DB_PASSWORD
Sample Console Output

Below is the GitHub Repository.

--

--

QADIR PERVEZ

passionate backend developer from India with 5 and more years of expertise in Laravel and Node.Js. Add me on LinkedIn https://www.linkedin.com/in/qadirpervez