Your One-Stop Guide to Laravel Commands

In this day and age, it's quite normal for a developer to have an understanding of consoles, and how to issue basic commands. But what if you could code your own custom commands to improve your workflow? If we look back to Laravel 3, you might remember that it offered tasks. Tasks were extremely helpful, but still came up short for more complex operations. Thankfully, Laravel 4 packs a beefed up Artisan that will make your life as a developer so much easier!


What is Artisan?

Artisan is the command line utility that was released in Laravel 3.

If you're not familiar with Laravel, then you might not be aware of Artisan. Artisan is the command line utility that was released in Laravel 3. If you've used other frameworks, you can compare Artisan to Oil in FuelPHP, ZFTool in Zend, or the Console in Symfony 2.

Artisan offers many useful commands that can help you perform various tasks, such as generating migrations or publishing a package's assets. In addition to the built-in commands, you can extend Artisan with your own commands.


Artisan's Foundations

This is where Artisan draws its power.

In Laravel 3, Artisan was written from scratch by Taylor Otwell (Laravel's creator), thus it was quite basic (although still awesome). Now that Laravel 4 is Composer based, it can use existing packages developed by other brilliant developers. As a result, Laravel 4 now depends on numerous packages from the Symfony framework. One of these such packages is the excellent Console Component.

If we take a look at the source of the Artisan application at Illuminate\Console\Application, we can see that the class, itself, extends Symfony\Component\Console\Application. This is where Artisan draws its power. Although Artisan makes use of Symfony's Console component, a lot of the common methods have been given more fluent Laravel-like aliases. So don't worry, it'll still feel like you're developing with Laravel!


Common Questions

Two questions typically pop up, when attempting to develop a new command.

Q Where should I put commands?

When you install a copy of Laravel, you'll find a predefined directory at app/commands. This directory is also in the classmap of your composer.json by default. This means that, once you've created a command, you'll need to run composer dump-autoload to generate an updated autoload file. If you don't, you'll receive errors, complaining that your command cannot be found.

If you're developing a package, you'll need to create a directory within your packages src/<vendor>/<package> directory to hold your commands. Throughout the Laravel 4 codebase, this directory is named Console. Remember to ensure that the directory is autoloaded in your packages composer.json.

Q How should I name commands?

Throughout the Laravel 4 codebase, all commands are suffixed with Command, and are named after the task that they perform. Let's say, for example, that you have a command that clears your cache. You might name this command, CacheClearCommand.


Basics of a Command

A command should perform a single task. Throughout the rest of this article, we're going to develop a user generator command. Let's review the basics of a command.

Laravel can generate this boilerplate code for you! Simply run:

This will create a skeleton command for you to modify, however, for the purposes of this tutorial, we'll go through the process of building a command from scratch, so that we can learn each piece of the process.

Command Name

All commands need to provide a name. This name is used to run the command from the console, and should describe the task that the command performs. While there is no convention for how your command is named, you might consider one of the following: namespace:group/command, namespace:command, or just command.

Command Description

All commands need to provide a description. The description is used when retrieving a list of available commands from Artisan, and when viewing the help docs for a command. Descriptions should briefly describe the task that the command performs.

If we were to open our console and fetch a list of available commands, we still won't be able to see our command listed.

To register our new command, open app/start/artisan.php and have a quick read through the default comment block that's in there. When we run Artisan from the console, this file is included; we'll be using it to bootstrap our commands. In this file, we have access to an $artisan variable that was declared prior to the file being included. Remember the Artisan application class that we looked at earlier? The one that extended the Symfony Console component? Well, $artisan is an instance of that class.

Let's add our command to make it available in the console.

Or, if you prefer the static syntax:

The add method accepts a command instance. Once our command has been added, we can access it from the console.

The command should also be listed in the available commands, as well as the help information.

If you receive any errors, ensure that you run composer dump-autoload from your applications root, after creating the command.


Colored Output

Outputting colored text to the console is a cinch in Artisan. There are four different helper methods to echo colored ANSI output.


Options and Arguments

An exciting new feature to Artisan is the ability to provide a command with options and arguments.

Arguments

Arguments are strings that you send through to a command. They must be given to a command in the order that they are defined. Consider the following command:

The name argument must be specified before the email argument.

Arguments can be defined as optional.

Options

Options are always optional, and are prefixed with two dashes, when provided.

Aside from being used as boolean switches, an option can be configured to accept a value or an array of values.

Defining Options and Arguments

Before we define our options and arguments, it's best to import the required Symfony classes (they're long and would be a pain to write out all the time). The two classes we need are Symfony\Component\Console\Input\InputOption and Symfony\Component\Console\Input\InputArgument.

Above our class declaration, we'll import both classes.

To define the options and arguments, you need to create two new methods: getArguments and getOptions. Both of these methods return an array of arguments or options. Let's make our command accept a name argument, and an age option.

Remember: Laravel can generate all of this boilerplate code for you. We're simply doing it manually for the purposes of reviewing each line in the class.

Now, we can provide a name argument and an age option from our console.

Both arguments and options are defined as multi-dimensional arrays. Let's take a closer look at the definitions for each of them.

Argument Definitions

The array definition for an argument accepts four keys, with only the first one (the arguments name) being required. The second key is the arguments mode and should be either InputArgument::OPTIONAL or InputArgument::REQUIRED. The third is the description, and the fourth key is a default value, if the mode is set to InputArgument::OPTIONAL.

Here's an argument using all the array keys.

Option Definitions

The array definition for an option accepts five keys with only the first (the options name) being required. The second key is a shortcut for the option (-a for example). The third is the options mode and can be one of the following values: InputOption::VALUE_NONE, InputOption::VALUE_REQUIRED, InputOption::VALUE_OPTIONAL, or InputOption::VALUE_IS_ARRAY. The fourth key is the options description, and the fifth key is a default value, if the mode is not InputOption::VALUE_NONE or InputOption::VALUE_REQUIRED.

Here's an option, using all of the array keys.

You can also combine the InputOption::VALUE_IS_ARRAY mode with InputOption::VALUE_REQUIRED or InputOption::VALUE_OPTIONAL.


Confirmations and Questions

Yet another exciting new feature to Artisan is its ability to request confirmation, or even ask the user a question. This makes developing interactive commands as simple as possible.

Confirmations

Using confirm, we can ask a user a question, and make them confirm with either "yes" or "no." Let's confirm that the user has entered their age correctly.

The first parameter is the question that you'd like to ask, and the second is the default value, if a user hits enter without typing anything.

Questions

Using ask, we can ask a user a question and expect a response from them. Instead of killing our command if the user specifies that they entered their age incorrectly, let's instead ask them to enter it again.


Command Dependencies

Dependency injection is an important step to ensure that your code is testable and future proof. Let's take our command a step further by injecting a model instance, so that we can generate the user. We'll begin by creating a user interface and user model.

Our UserInterface doesn't actually define any method implementations, as this is just an example. For a real world application, you'd define the methods you'd expect on your model.

Now that we have our User model implementing our UserInterface, we can continue to setup our dependency in our command. I'm going to add a bit more to our generate command, and interact with the User model that's injected.

The first thing you should notice is that the command now has a constructor. This constructor accepts a single parameter and we've type hinted the UserInterface, so we know that the class we get implements the methods defined on the interface. Command constructors should also call the parent constructor.

In the fire method of the command, we're directly assigning the properties on the User model instance. We're also using a loop to continue asking the user if they have entered their age correctly. Lastly, the user is saved to the database and we output to the console that the user was generated and saved.

But wait! Before we can use the command, we need to inject an instance of our User model.

If you have a database setup and configured correctly, you should now be able to run the command and have a new user saved to the database!


Package Commands

If you're developing a package in Laravel, you might want to include commands. Registering commands from packages is mostly the same process, except you don't (or can't) add the command in app/start/artisan.php. Instead, you resolve them with Artisan from within your packages service provider.

The commands method can accept any number of arguments, and will resolve the command out of the application container when Artisan is started.


Conclusion

When you compare Artisan in Laravel 4 to its Laravel 3 counterpart, you'll quickly find that the improvements are monumental. Commands can now be bound to the IoC container and include dependency injection, provide colored ANSI output, use arguments and options, and request user interaction.

The power of Artisan, thanks to Symfony's Console component, is unbelievable. Commands are going to play a huge role, as we move forward - so get on board early!

Tags:

Comments

Related Articles