當前位置: 首頁> 最新文章列表> 如何在使用pclose函數時捕獲並正確處理標準錯誤輸出?實用技巧分享

如何在使用pclose函數時捕獲並正確處理標準錯誤輸出?實用技巧分享

gitbox 2025-09-12

3. 單獨捕獲標準錯誤輸出的方法

如果你希望分別獲取標準輸出和標準錯誤輸出,可以利用臨時文件或者命名管道:

方案一:利用臨時文件存儲標準錯誤

<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&gt; <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>

這樣你可以分別獲取兩個輸出流,便於更細緻的錯誤處理。


4. 使用proc_open獲得更靈活的管道控制

proc_open()允許直接操作標準輸入、輸出和錯誤,使用起來更複雜,但功能更強大。

 <span><span><span class="hljs-variable">$descriptorspec</span></span><span> = [
    </span><span><span class="hljs-number">0</span></span><span> =&gt; [</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> =&gt; [</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> =&gt; [</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>

此方法能精準分離兩個輸出流,更適合複雜需求。