New in Symfony 4.1: Prepared commands
February 28, 2018 • Published by Javier Eguiluz
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Contributed by
Hamza Amrouche
in #24763.
In Symfony 4.1 we improved the Process component to allow writing "prepared commands", a concept similar to prepared statements in SQL. The basic idea is to replace some parts of the command with placeholders whose values you provide later when actually running the command (or via environment variables):
1 2 3 4
use Symfony\Component\Process\Process;
$process = new Process('ls -lsa "${:path}"');
$process->run(null, ['path' => '/path/to/some/dir']);
Placeholders must follow the "${:placeholder_name}"
syntax strictly, which
has nothing to do with Twig, except for the coincidence in the use of brackets.
If some placeholder value is missing when running the command, you'll get an
InvalidArgumentException
.
In addition to passing the placeholder values as the second argument of the
run()
method you can also pass them in the Process
class constructor:
1 2 3 4
use Symfony\Component\Process\Process;
$process = new Process('ls -lsa "${:path}"', null, ['path' => '/path/to/some/dir']);
$process->run();
One of the best features of prepared commands is that placeholder values are escaped automatically, which makes your life as a developer easier and ensures that commands will always work as expected.
1 2 3 4 5 6 7
$process = new Process('mysqldump --user="${:db_user}" --password="${:db_pass}" "${:db_name}" > "${:db_backup_path}"');
$process->run(null, [
'db_user' => getenv('DB_USER'),
'db_password' => getenv('DB_PASS'),
'db_name' => 'symfony',
'db_backup_path' => '/var/backup/db-'.time().'.sql',
]);
If you don't like the idea of using placeholders in your commands for some reason, the Process component also allows since Symfony 3.3 to pass an array where the first element is the command to run and the rest of the array elements are its options and arguments, allowing you to build a complex command programmatically:
1 2 3 4 5 6 7
$process = new Process(array(
'mysqldump',
'--user='.getenv('DB_USER'),
'--password='.getenv('DB_PASS'),
$dbName,
));
$process->run();
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
Thx Javier :)
Thank you!
But, in my OPINION, at first it was necessary to release this feature, and then to remove `ProcessBuilder`.
Now I do not understand how to escape arguments. Probably, it is necessary to use native `escapeshellarg`. Which I don't think is good.
Following along a bit, the behaviour have changed. Now, it should be something like this on unix:
$process = new Process('ls -lsa "${:path}"', null, ['path' => '/path/to/some/dir']);
(See https://github.com/symfony/symfony/pull/34848)