Contributed by
Hamza Amrouche
in #24763.

更新: 此功能在我们找到更佳实现方式之前已被恢复到 Pull Request #26372


在 Symfony 4.1 中我们改进了 Process组件 以令它能够 "prepared commands(预置命令)",这个概念类似于 SQL 中的 prepared 声明。其基本用法是,用占位符来替换命令中的某些部分,再把占位符的值在后面真正运行命令时(或通过环境变量)提供出来:

1
2
3
4
use Symfony\Component\Process\Process;
 
$process = new Process('ls -lsa {{ path }}');
$process->run(null, ['path' => '/path/to/some/dir']);

占位符必须严格遵守 {{ placeholder_name }} 语法,这与 Twig 毫无关系,除了括号碰巧一样之外。运行命令时,如果某些占位符的值丢失,你会得到一个 InvalidArgumentException

除了在 run() 方法中把占位符的值作为第二个参数传入之外,你也可以在 Process 类的构造器中传入它们:

1
2
3
4
use Symfony\Component\Process\Process;
 
$process = new Process('ls -lsa {{ path }}', null, ['path' => '/path/to/some/dir']);
$process->run();

预置命令的最强之处在于,占位符的值是被自动转义的,这就令开发者节省了大量时间,进而确保命令始终如预期般工作。

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',
]);

如果由于某些原因,你不愿意在自己的命令中使用占位符,Process 组件自 Symfony 3.3 起允许传入一个数组,其第一个元素是待运行的命令,剩余所有元素都是它的选项以及参数,让你能够程式化地构造出复杂的命令:

1
2
3
4
5
6
7
$process = new Process(array(
    'mysqldump',
    '--user='.getenv('DB_USER'),
    '--password='.getenv('DB_PASS'),
    $dbName,
));
$process->run();