The command-line interface (CLI) can be a powerful tool for developers. You can use it as part of your development workflow to add new features to your application and to perform tasks in a production environment. Laravel allows you to create Artisan commands
to add bespoke functionality to your application. It also provides a Process facade
that you can use to run OS (operating system) processes from your Laravel application to perform tasks such as running custom shell scripts. In this article, we’ll explore what Artisan commands are and provide tips and tricks for creating and testing them. We’ll also look at how to run operating system (OS) processes from your Laravel application and test they are called correctly.
What are Artisan commands?
Artisan commands can be run from the CLI to perform many tasks on a Laravel app. They can allow a more streamlined development process and be used to perform tasks in a production environment. As a Laravel developer, you’ll have likely already used some built-in Artisan commands, such as php artisan make:model
, php artisan migrate
, and php artisan down
. For example, some Artisan commands can be used as part of the development process, such as php artisan make:model
and php artisan make:controller
. Typically, these wouldn’t be run in a production environment and are used purely to speed up the development process by creating boilerplate files. Some Artisan commands can be used to perform tasks in a production environment, such as php artisan migrate
and php artisan down
. These are used to perform tasks, such as running database migrations and taking your application offline while you perform maintenance or roll out an update. Thus, Artisan commands can be used to perform a variety of tasks and can be used in both development and production environments.
Creating your own Artisan commands
Now that we have a better understanding of what Artisan commands are, let’s look at how we can create our own.
Getting input from users
To give some examples of what we can do with Artisan commands, let’s take a look at a common use-case for them that you may across in your own projects: creating a new super admin in the database. In this example, we need the following pieces of information to create a new super admin:
- Name
- Email address
- Password
Let’s create the command to do this. We’ll call the command CreateSuperAdmin
and create it by running the following command:
php artisan make:command CreateSuperAdmin
This command will create a new app/Console/Commands/CreateSuperAdmin.php
file. We’ll assume that we have access to a createSuperAdmin
method in a UserService
class. For the purposes of this article, we don’t need to know what it does or how it works since we’re focused on how the commands work. The command class created by the make:command
command will look something like this:
namespace App\Console\Commands;
use Illuminate\Console\Command;
class CreateSuperAdmin extends Command {
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:create-super-admin';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*/
public function handle(): void {
//
}
}
Now we want to add our arguments to the command so that we can accept the name, email, and password for each new user. We can do this by updating the signature
property of the command class. The signature
property is used to define the name of the command, the arguments, and the options that the command accepts. The signature
property should look something like this:
protected $signature = 'app:create-super-admin {--email=} {--password=} {--name=}';
We may also want to add an option to the command to allow the user to specify whether an email should be sent to confirm the account. By default, we’ll assume the user shouldn’t be sent the email. To add this option to the code, we can update the signature
property to look like this:
protected $signature = 'app:create-super-admin {--email=} {--password=} {--name=} {--send-email}';
It’s important to also update the command’s description
property to describe what it does. This will be displayed when the user runs the php artisan list
or php artisan help
commands.
Now that we have our options configured to accept input, we can pass these options to our createSuperAdmin
method. Let’s take a look at what our command class will look like now:
namespace App\Console\Commands;
use App\Services\UserService;
use Illuminate\Console\Command;
class CreateSuperAdmin extends Command {
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:create-super-admin {--email=} {--password=} {--name=} {--send-email}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Store a new super admin in the database';
/**
* Execute the console command.
*/
public function handle(UserService $userService): int {
$userService->createSuperAdmin(
email: $this->option('email'),
password: $this->option('password'),
name: $this->option('name'),
sendEmail: $this->option('send-email'),
);
$this->components->info('Super admin created successfully!');
return self::SUCCESS;
}
}
Our command should now be ready to run. We can run it using the following command:
php artisan app:create-super-admin --email="hello@example.com" --name="John Doe" --password="password" --send-email
If we wanted to take this a step further, we may also want to add questions to the command so that the user can be prompted to enter the information if they don’t provide it as an argument or option. This can provide a friendly user experience for developers, especially if they are new to using the command or if it has several arguments and options. If we wanted to update our command to use questions, our command may now look something like this:
namespace App\Console\Commands;
use App\Services\UserService;
use Illuminate\Console\Command;
class CreateSuperAdmin extends Command {
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:create-super-admin {--email=} {--password=} {--name=} {--send-email}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Store a new super admin in the database';
/**
* Execute the console command.
*/
public function handle(UserService $userService): int {
$userService->createSuperAdmin(
email: $this->getInput('email'),
password: $this->getInput('password'),
name: $this->getInput('name'),
sendEmail: $this->getInput('send-email'),
);
$this->components->info('Super admin created successfully!');
return self::SUCCESS;
}
public function getInput(string $inputKey): string {
return match($inputKey) {
'email' => $this->option('email') ?? $this->ask('Email'),
'password' => $this->option('password') ?? $this->secret('Password'),
'name' => $this->option('name') ?? $this->ask('Name'),
'send-email' => $this->option('send-email') === true ? $this->option('send-email') : $this->confirm('Send email?'),
default => null,
};
}
}
As you can see, we’ve added a new getInput
method to the command class. Within this method, we’re checking whether an argument has been passed to the command. If it hasn’t, we prompt the user for input. You may have also noticed that we’ve used the secret
method for getting the new password. This method is used so that we can hide the password from the terminal output. If we didn’t use the secret
method, the password would be displayed in the terminal output. Similarly, we’ve also used the confirm
method for determining whether to send an email to the new user. This will prompt the user with a yes or no question, so it’s a good way to get a Boolean value from the user rather than using the ask
method.
Running
Source link