流程组件

编辑该页面

警告:你浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 5.2,不再维护。

这个页面的更新版本Symf欧宝娱乐app下载地址ony 6.2(当前的稳定版本)。

流程组件

在子过程中流程组件执行命令。

安装

1
美元作曲家需要symfony /过程欧宝娱乐app下载地址

请注意

如果你安装这个组件之外的Symfony应用程序,你必须要求欧宝娱乐app下载地址供应商/ autoload.php文件在你的代码,使作曲家提供的类加载机制。读这篇文章为更多的细节。

使用

过程类在子流程执行一个命令,照顾操作系统之间的差异和逃避参数来防止安全问题。它取代PHP函数执行,passthru,shell_exec系统:

1 2 3 4 5 6 7 8 9 10 11 12
使用欧宝娱乐app下载地址\组件\过程\异常\ProcessFailedException;使用欧宝娱乐app下载地址\组件\过程\过程;美元过程=过程([“ls”,“文理学院”]);美元过程- >run ();/ /命令完成后执行如果(!美元过程- >isSuccessful ()) {ProcessFailedException (美元过程);}回声美元过程- >getOutput ();

getOutput ()方法总是返回命令的标准输出的整个内容getErrorOutput ()错误输出的内容。或者,getIncrementalOutput ()getIncrementalErrorOutput ()方法返回新的输出自上次电话。

clearOutput ()清除输出的内容和方法clearErrorOutput ()清除错误输出的内容。

您还可以使用过程类的每个构建时生成的输出。默认情况下,循环等待新的输出到下一个迭代之前:

1 2 3 4 5 6 7 8 9 10
美元过程=过程([“ls”,“文理学院”]);美元过程- >开始();foreach(美元过程作为美元类型= >美元数据){如果(美元过程::出= = =美元类型){回声“从stdout \ nRead:“美元数据;}其他的{/ /流程:美元:呃= = = $类型回声“从stderr \ nRead:“美元数据;}}

提示

内部流程组件使用一个PHP迭代器输出时生成。迭代器是通过公开getIterator ()方法允许自定义其行为:

1 2 3 4 5 6
美元过程=过程([“ls”,“文理学院”]);美元过程- >开始();美元迭代器=美元过程- >getIterator (美元过程::ITER_SKIP_ERR |美元过程::ITER_KEEP_OUTPUT);foreach(美元迭代器作为美元数据){回声美元数据“\ n”;}

mustRun ()方法是相同的run (),除了它将抛出一个ProcessFailedException如果进程无法成功执行(即过程与一个非零退出代码):

1 2 3 4 5 6 7 8 9 10 11 12
使用欧宝娱乐app下载地址\组件\过程\异常\ProcessFailedException;使用欧宝娱乐app下载地址\组件\过程\过程;美元过程=过程([“ls”,“文理学院”]);试一试{美元过程- >mustRun ();回声美元过程- >getOutput ();}(ProcessFailedException美元异常){回声美元异常- >getMessage ();}

提示

你可以通过使用最后的输出时间间隔,以秒为单位getLastOutputTime ()方法。该方法返回如果流程没有开始!

配置过程选项

5.2

功能配置过程选项是在Symfony 5.2中引入的。欧宝娱乐app下载地址

欧宝娱乐app下载地址Symfony使用PHPproc_open函数运行的进程。您可以配置选项传递到other_options的观点proc_open ()使用setoption ()方法:

1 2 3
美元过程=过程([“……”,“……”,“……”]);/ /这个选项允许子流程的主要脚本退出后继续运行美元过程- >setoption ([“create_new_console”= >真正的]);

从OS Shell使用特性

推荐的方法是使用数组的参数定义的命令。这样可以避免任何逃离,并允许无缝地发送信号(如停止进程运行时):

1 2
美元过程=过程([“/道路/命令”,”,选择“,“参数”,“等等。”]);美元过程=过程([/道路/ / php的,“——定义”,“memory_limit = 1024”,“/道路/ / script.php”]);

如果你需要使用流重定向,有条件执行,或任何其他功能提供的外壳你的操作系统,您还可以使用命令定义为字符串fromShellCommandline ()静态工厂。

每个操作系统提供了一个不同的命令行语法,所以它变成了你的责任逃避和可移植性。

当使用字符串定义命令,变量参数作为环境变量使用第二个参数传递run (),mustRun ()start ()方法。引用他们也依赖于:

1 2 3 4 5 6 7 8
/ /在类unix操作系统(Linux, macOS)美元过程=过程::fromShellCommandline (“回声“元信息””);/ /在Windows上美元过程=过程::fromShellCommandline (“回声”消息!”);/ /类unix和Windows美元过程- >运行(,(“消息”= >“输出的东西”]);

如果你喜欢创建便携式独立于操作系统的命令,您可以编写上面的命令如下:

1 2
/ /同样的工作在Windows、Linux和macOS美元过程=过程::fromShellCommandline (”echo ${:消息}”);

便携式命令需要使用语法,是特定于组件:当封闭一个变量名“$ {:}”准确,过程对象将取代它与逃值,或者将会失败如果没有找到该变量在环境变量的列表附加到命令。

设置环境变量的过程

的构造函数过程类和它的所有方法执行相关流程(run (),mustRun (),start ()等)允许通过一组环境变量设置在运行过程:

1 2 3
美元过程=过程([“……”),,(“ENV_VAR_NAME”= >“价值”]);美元过程=过程::fromShellCommandline (“……”,,(“ENV_VAR_NAME”= >“价值”]);美元过程- >运行(,(“ENV_VAR_NAME”= >“价值”]);

除了env var通过明确、流程继承系统中定义的所有env var。你可以防止这种通过设置你想要删除的env var:

1 2 3 4
美元过程=过程([“……”),,(“APP_ENV”= >,“欧宝娱乐app下载地址SYMFONY_DOTENV_VARS”= >]);

获得实时的过程输出

当执行一个长时间运行的命令(如rsync远程服务器),可以实时反馈给最终用户通过一个匿名函数run ()方法:

1 2 3 4 5 6 7 8 9 10
使用欧宝娱乐app下载地址\组件\过程\过程;美元过程=过程([“ls”,“文理学院”]);美元过程- >运行(函数(美元类型,美元缓冲){如果(过程::呃= = =美元类型){回声“呃>”美元缓冲;}其他的{回声“>”美元缓冲;}});

请注意

此功能无法正常工作在服务器上使用PHP输出缓冲。在这些情况下,禁用output_buffering或使用PHP选项ob_flushPHP函数强迫发送输出缓冲区。

异步运行的流程

你也可以异步启动子流程,然后让它运行,检索输出和状态在你的主要过程中当你需要它。使用start ()开始一个异步的过程,方法正在()方法检查过程和完成getOutput ()方法得到的输出:

1 2 3 4 5 6 7 8
美元过程=过程([“ls”,“文理学院”]);美元过程- >开始();(美元过程- >正在()){/ /等待过程完成}回声美元过程- >getOutput ();

你也可以等待一个异步过程结束,如果你开始和完成做其他东西:

1 2 3 4 5 6 7 8
美元过程=过程([“ls”,“文理学院”]);美元过程- >开始();/ /……做其他的事情美元过程- >wait ();/ /……后做事情的过程已经完成了吗

请注意

wait ()方法阻断,这意味着您的代码将在这条线,直到停止外部过程完成。

请注意

如果一个响应发送之前子进程有机会完成,服务器进程就会被杀死(根据您的操作系统)。这意味着你的任务将被停止。运行一个异步的过程是不一样的运行过程,它的父进程。

如果你想让你的进程在请求/响应周期,你可以利用kernel.terminate事件,运行命令同步在这个事件。请注意,kernel.terminate只有你使用PHP-FPM叫做。

谨慎

也要小心,如果你这样做,说PHP-FPM过程将不会提供给任何新的请求,直到子进程结束。这意味着您可以快速块FPM池如果你不够小心。这就是为什么通常方式最好不要做任何花哨的东西即使在发送请求,但是使用一个工作队列。

wait ()接受一个可选参数:一个反复调用回调而进程仍在运行,通过在输出和它的类型:

1 2 3 4 5 6 7 8 9 10
美元过程=过程([“ls”,“文理学院”]);美元过程- >开始();美元过程- >等待(函数(美元类型,美元缓冲){如果(过程::呃= = =美元类型){回声“呃>”美元缓冲;}其他的{回声“>”美元缓冲;}});

而不是等到过程完成后,您可以使用waitUntil ()方法继续或停止等待基于一些PHP逻辑。下面的例子开始一个长时间运行的流程,检查其输出等到完全初始化:

1 2 3 4 5 6 7 8 9 10 11
美元过程=过程([“/ usr / bin / php”,“slow-starting-server.php”]);美元过程- >开始();/ /……做其他的事情/ /等待,直到给定的匿名函数返回true美元过程- >waitUntil (函数(美元类型,美元输出){返回美元输出= = =“准备好了。等待命令……”;});/ /……做事过程后,准备好了吗

标准输入流的一个过程

流程开始之前,你可以指定它的标准输入使用setInput ()方法或4参数的构造函数。所提供的输入可以是一个字符串,或流资源可否认的对象:

1 2 3
美元过程=过程([“猫”]);美元过程- >setInput (“foobar”);美元过程- >run ();

当这个输入完全写入子进程的标准输入,相应的管道关闭。

为了写子进程的标准输入运行时组件提供了InputStream类:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
美元输入=InputStream ();美元输入- >写(“foo”);美元过程=过程([“猫”]);美元过程- >setInput (美元输入);美元过程- >开始();/ /……阅读过程输出或做其他事情美元输入- >写(“酒吧”);美元输入- >close ();美元过程- >wait ();/ /将回声:foobar回声美元过程- >getOutput ();

write ()方法接受标量、资源或流可否认的对象作为参数。在上面的示例中所示,您需要显式地调用close ()方法当你完成写作到子进程的标准输入。

使用PHP作为进程的标准输入流

流程的输入也可以定义使用PHP流:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
美元= fopen (php: / /临时的,“w +”);美元过程=过程([“猫”]);美元过程- >setInput (美元);美元过程- >开始();写入文件(美元,“foo”);/ /……阅读过程输出或做其他事情写入文件(美元,“酒吧”);fclose (美元);美元过程- >wait ();/ /将回声:“foobar”回声美元过程- >getOutput ();

使用遥控和企业模式

以上例子表明,程序控制流程的输入(使用setInput ()),这一过程的输出(使用getOutput ())。流程组件有两个特殊的模式,调整程序和过程之间的关系:电传(tty)和pseudo-teletype(企业)。

在遥控模式下,你将流程的输入和输出连接到您的程序的输入和输出。这允许例如打开一个编辑器像Vim或者纳米作为一个过程。通过调用启用遥控模式setTty ():

1 2 3 4 5 6 7
美元过程=过程([“活力”]);美元过程- >setTty (真正的);美元过程- >run ();/ /输出连接到终端,它不再是可能的/ /读取或修改过程的输出!转储(美元过程- >getOutput ());/ /空

在企业模式下,程序的行为作为一个终端的过程而不是一个简单的输入和输出。一些程序的表现会与真正的终端进行交互,而不是另一个程序。例如,一些程序和一个终端时提示输入密码。使用setPty ()启用这个模式。

停止一个进程

任何异步过程可以停在任何时间stop ()方法。该方法接受两个参数:一个超时和一个信号。一旦超时,信号发送到正在运行的进程。默认的信号发送到一个过程SIGKILL。请阅读信号下面文档欧宝体育电话找到更多关于信号处理的流程组件:

1 2 3 4 5 6
美元过程=过程([“ls”,“文理学院”]);美元过程- >开始();/ /……做其他的事情美元过程- >停止(3、信号情报);

独立执行的PHP代码

如果你想要执行一些PHP代码隔离,使用PhpProcess而不是:

1 2 3 4 5 6 7
使用欧宝娱乐app下载地址\组件\过程\PhpProcess;美元过程=PhpProcess (< < < EOF < ?='Hello World' ?> EOF);美元过程- >run ();

过程超时

默认流程有一个60秒的超时,但是你可以改变它通过不同的超时时间(以秒为单位)setTimeout ()方法:

1 2 3 4 5
使用欧宝娱乐app下载地址\组件\过程\过程;美元过程=过程([“ls”,“文理学院”]);美元过程- >setTimeout (3600年);美元过程- >run ();

如果超时,ProcessTimedOutException抛出。

对于长时间运行的命令,这是你的责任来执行超时定期检查:

1 2 3 4 5 6 7 8 9 10 11
美元过程- >setTimeout (3600年);美元过程- >开始();(美元条件){/ /……/ /检查是否超时美元过程- >checkTimeout ();usleep (200000年);}

提示

你可以开始时间使用过程getStartTime ()方法。

5.1

getStartTime ()方法是在Symfony 5.1中引入的。欧宝娱乐app下载地址

过程闲置超时

前款规定的超时相比,闲置超时只考虑时间自上次输出是由过程:

1 2 3 4 5 6
使用欧宝娱乐app下载地址\组件\过程\过程;美元过程=过程([“something-with-variable-runtime”]);美元过程- >setTimeout (3600年);美元过程- >setIdleTimeout (60);美元过程- >run ();

在上面的案例中,一个过程被认为是超时,当总运行时间超过3600秒,或过程不会产生任何输出60秒。

过程的信号

当异步运行一个程序时,你可以把它与POSIX信号信号()方法:

1 2 3 4 5 6 7
使用欧宝娱乐app下载地址\组件\过程\过程;美元过程=过程([“发现”,' / ',“- name”,“兔子”]);美元过程- >开始();/ /将发送SIGKILL过程美元过程- >信号(SIGKILL);

过程Pid

您可以访问pid一个运行的进程getPid ()方法:

1 2 3 4 5 6
使用欧宝娱乐app下载地址\组件\过程\过程;美元过程=过程([“/ usr / bin / php”,“worker.php”]);美元过程- >开始();美元pid=美元过程- >getPid ();

禁用输出

标准输出和错误输出总是从底层获取过程,它可能是方便禁用输出在某些情况下节省内存。使用disableOutput ()enableOutput ()这个功能切换:

1 2 3 4 5
使用欧宝娱乐app下载地址\组件\过程\过程;美元过程=过程([“/ usr / bin / php”,“worker.php”]);美元过程- >disableOutput ();美元过程- >run ();

谨慎

你不能启用或禁用在流程运行时的输出。

如果您禁用输出,你不能访问getOutput (),getIncrementalOutput (),getErrorOutput (),getIncrementalErrorOutput ()setIdleTimeout ()

然而,可以通过回调的开始,运行mustRun方法来处理过程输出流的方式。

找到一个可执行文件

流程组件提供了一个实用程序类ExecutableFinder的绝对路径查找并返回一个可执行:

1 2 3 4 5
使用欧宝娱乐app下载地址\组件\过程\ExecutableFinder;美元executableFinder=ExecutableFinder ();美元chromedriverPath=美元executableFinder- >找到(“chromedriver”);/ / $ chromedriverPath = / usr /地方/ bin / chromedriver(结果将是不同的在你的电脑上)

find ()方法还需要额外的参数指定一个默认值返回和额外的目录在哪里寻找可执行:

1 2 3 4
使用欧宝娱乐app下载地址\组件\过程\ExecutableFinder;美元executableFinder=ExecutableFinder ();美元chromedriverPath=美元executableFinder- >找到(“chromedriver”,“/道路/ / chromedriver”,(“本地bin /”]);

找到可执行PHP二进制文件

该组件还提供了一个特殊的实用程序类PhpExecutableFinder它返回PHP二进制可执行文件的绝对路径可用服务器上:

1 2 3 4 5
使用欧宝娱乐app下载地址\组件\过程\PhpExecutableFinder;美元phpBinaryFinder=PhpExecutableFinder ();美元phpBinaryPath=美元phpBinaryFinder- >find ();/ / $ phpBinaryPath = / usr /地方/ bin / php的(结果将是不同的在你的电脑上)

检查TTY支持

该组件提供的另一个工具是一个方法调用isTtySupported ()它返回是否TTY支持当前操作系统:

1 2 3
使用欧宝娱乐app下载地址\组件\过程\过程;美元过程= (过程())- >setTty(过程::isTtySupported ());
这项工作,包括代码示例,许可下Creative Commons冲锋队3.0许可证。