Hamza Amrouche
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();
Published in #Living on the edge