如果你希望分别获取标准输出和标准错误输出,可以利用临时文件或者命名管道:
<span><span><span class="hljs-variable">$stderrFile</span></span><span> = </span><span><span class="hljs-title function_ invoke__">tempnam</span></span><span>(</span><span><span class="hljs-title function_ invoke__">sys_get_temp_dir</span></span><span>(), </span><span><span class="hljs-string">'stderr'</span></span><span>);
</span><span><span class="hljs-variable">$cmd</span></span><span> = </span><span><span class="hljs-string">"ls /nonexistent 2> <span class="hljs-subst">$stderrFile</span></span></span><span>";
</span><span><span class="hljs-variable">$handle</span></span><span> = </span><span><span class="hljs-title function_ invoke__">popen</span></span><span>(</span><span><span class="hljs-variable">$cmd</span></span><span>, </span><span><span class="hljs-string">"r"</span></span><span>);
</span><span><span class="hljs-variable">$output</span></span><span> = </span><span><span class="hljs-string">''</span></span><span>;
</span><span><span class="hljs-keyword">while</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">feof</span></span><span>(</span><span><span class="hljs-variable">$handle</span></span><span>)) {
</span><span><span class="hljs-variable">$output</span></span><span> .= </span><span><span class="hljs-title function_ invoke__">fread</span></span><span>(</span><span><span class="hljs-variable">$handle</span></span><span>, </span><span><span class="hljs-number">1024</span></span><span>);
}
</span><span><span class="hljs-variable">$status</span></span><span> = </span><span><span class="hljs-title function_ invoke__">pclose</span></span><span>(</span><span><span class="hljs-variable">$handle</span></span><span>);
</span><span><span class="hljs-variable">$stderr</span></span><span> = </span><span><span class="hljs-title function_ invoke__">file_get_contents</span></span><span>(</span><span><span class="hljs-variable">$stderrFile</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">unlink</span></span><span>(</span><span><span class="hljs-variable">$stderrFile</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"标准输出:\n<span class="hljs-subst">$output</span></span></span><span>\n";
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"标准错误:\n<span class="hljs-subst">$stderr</span></span></span><span>\n";
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"命令返回状态: <span class="hljs-subst">$status</span></span></span><span>\n";
</span></span>
这样你可以分别获取两个输出流,便于更细致的错误处理。
proc_open()允许直接操作标准输入、输出和错误,使用起来更复杂,但功能更强大。
<span><span><span class="hljs-variable">$descriptorspec</span></span><span> = [
</span><span><span class="hljs-number">0</span></span><span> => [</span><span><span class="hljs-string">"pipe"</span></span><span>, </span><span><span class="hljs-string">"r"</span></span><span>], </span><span><span class="hljs-comment">// 标准输入</span></span><span>
</span><span><span class="hljs-number">1</span></span><span> => [</span><span><span class="hljs-string">"pipe"</span></span><span>, </span><span><span class="hljs-string">"w"</span></span><span>], </span><span><span class="hljs-comment">// 标准输出</span></span><span>
</span><span><span class="hljs-number">2</span></span><span> => [</span><span><span class="hljs-string">"pipe"</span></span><span>, </span><span><span class="hljs-string">"w"</span></span><span>] </span><span><span class="hljs-comment">// 标准错误</span></span><span>
];
</span><span><span class="hljs-variable">$process</span></span><span> = </span><span><span class="hljs-title function_ invoke__">proc_open</span></span><span>(</span><span><span class="hljs-string">'ls /nonexistent'</span></span><span>, </span><span><span class="hljs-variable">$descriptorspec</span></span><span>, </span><span><span class="hljs-variable">$pipes</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">is_resource</span></span><span>(</span><span><span class="hljs-variable">$process</span></span><span>)) {
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$pipes</span></span><span>[</span><span><span class="hljs-number">0</span></span><span>]);
</span><span><span class="hljs-variable">$stdout</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_get_contents</span></span><span>(</span><span><span class="hljs-variable">$pipes</span></span><span>[</span><span><span class="hljs-number">1</span></span><span>]);
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$pipes</span></span><span>[</span><span><span class="hljs-number">1</span></span><span>]);
</span><span><span class="hljs-variable">$stderr</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_get_contents</span></span><span>(</span><span><span class="hljs-variable">$pipes</span></span><span>[</span><span><span class="hljs-number">2</span></span><span>]);
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$pipes</span></span><span>[</span><span><span class="hljs-number">2</span></span><span>]);
</span><span><span class="hljs-variable">$status</span></span><span> = </span><span><span class="hljs-title function_ invoke__">proc_close</span></span><span>(</span><span><span class="hljs-variable">$process</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"标准输出:\n<span class="hljs-subst">$stdout</span></span></span><span>\n";
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"标准错误:\n<span class="hljs-subst">$stderr</span></span></span><span>\n";
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"命令返回状态: <span class="hljs-subst">$status</span></span></span><span>\n";
}
</span></span>
此方法能精准分离两个输出流,更适合复杂需求。