CLI Command
The php-command
serves as an advanced foundation for developing robust CLI applications.
Leveraging the capabilities of
the Symfony Console component,
this template is designed to accommodate complex business logic and extensive
functionalities. Unlike single-file script, which is intended for
simpler tasks, this template is structured to evolve into a comprehensive CLI
tool.
Symfony Console
The Symfony Console component brings a wealth of features for building CLI applications, making it a go-to choice for developers looking to create robust, scalable command-line tools. One of its main features is the ability to define commands, options, and arguments in a structured manner. This is beneficial for applications that have multiple functionalities, as each can be encapsulated into separate commands.
For instance, in the app.php
example, two commands—JokeCommand
and SayHelloCommand
—are defined and added to the application. The add
method
allows you to register multiple commands easily, creating a modular CLI tool. By
doing this, you enable your application to handle diverse tasks, each accessed
via its own command.
Another advantage is the ability to set a default command
using setDefaultCommand
, which is executed when no command is explicitly
specified. This is particularly useful for applications that have a primary
function which is most commonly used.
Beyond commands, Symfony Console also offers robust error handling, input/output abstraction, and helpers for generating styled console output. All these features collectively contribute to creating a professional-grade CLI application.
Example commands
This template includes two example commands: SayHelloCommand
and JokeCommand
.
The SayHelloCommand
command:
- Called using
app:say-hello
. - Provides additional help details for the user.
- Prints
Hello, Symfony console!
when run. - Signals successful execution by returning a success status.
This command is a good example of a simple command that can be used as a starting point.
The JokeCommand
command:
- Called with the command
app:joke
. - Accepts an optional
topic
parameter for the joke. - Retrieves a joke from an external API based on the topic.
- Displays the setup and punchline of the joke.
- Shows an error message if it can't retrieve a joke.
- Returns a success status if the joke is displayed, or a failure status otherwise.
This is a more complex command that demonstrates how to handle arguments and options, as well as how to make external API calls.
Both commands are registered in the app.php
file and can be tested with unit
tests.
This template provides a robust set of unit tests to get you started.
Command structure
In the CLI application, three key components build the overall structure:
-
Bootstrap file: This is the script that initializes your application. It looks for Composer's autoload file to include all dependencies. Once it finds it, it then loads your application by requiring the
app.php
file. -
Application loader: Defined in
app.php
, this file is where you initialize the Symfony Console Application object. You add commands to it, likeJokeCommand
andSayHelloCommand
, and finally run the application. This acts as the heart of your CLI application, tying together all the commands you've created. -
Command class(es): These are the actual commands your application will execute. Each command class is responsible for a specific action like saying hello or telling a joke. These classes extend Symfony's Command class and are where you define your business logic. Optionally, you may also include unit tests for your commands to verify they work as expected.
These components work together to create a cohesive CLI application, allowing for extensible and maintainable code.
Getting Started
Depending on the complexity of your CLI application, you may chose a simpler
SayHelloCommand
or a more complex JokeCommand
as a starting point.
Start by renaming the command class and file to match your application.
Next, adjust the configure
function to define the command name, description,
and other details. You can also add arguments and options here.
Your core logic will be housed in the execute
function. Simply replace the
existing code with your own.
Lastly, you can update unit tests in the tests/phpunit/Command
directory.
You can then run your script from the command line
using ./php-command
.
Authoring tests
This template includes
a tests/phpunit/Unit/Commands
directory with a sample Unit tests.
The Symfony Console component provides a CommandTester
class that allows you
to
test commands in a controlled environment. This is useful for testing commands
that make external API calls or interact with the file system.
The CommandTester
class provides methods for simulating user input and
capturing output, allowing you to test the command's behavior without actually
running it.
This template
provides CommandUnitTestCase.php
base class for all command Unit tests. It also includes several traits.
SayHelloCommandTest.php
and
JokeCommandTest.php
are two examples of Unit tests for SayHelloCommand
and JokeCommand
commands.
Distribution
Distribution of CLI applications is a bit more complex than that of web. While web applications can be distributed as source code, CLI applications are usually distributed as a single executable file. This is called a PHAR file.
This template provides a composer build
command and GitHub action for building
a PHAR file. See PHP Packaging for more details.
An alternative approach is to use your command as a Composer package. Once published to the Packagist.org, the Composer packages registry, the command binary file will be available to be called from within Composer scripts.
This template provides a configuration entry within composer.json
that would
place the command bootstrap file in the vendor/bin
directory of the project
requiring the command as dependency.