ZetCode

PHP pclose 函数

最后修改于 2025 年 4 月 3 日

PHP 的 pclose 函数用于关闭由 popen 打开的进程文件指针。在处理进程管道时,这是进行正确资源清理的关键。

基本定义

pclose 函数会终止与管道关联的进程并关闭文件指针。它会返回进程的终止状态。

语法:pclose(resource $handle): int。该函数接收来自 popen 的管道句柄,并返回进程的退出状态。

基本的 pclose 示例

这展示了 pclose 在进程管道中最简单的用法。

basic_pclose.php
<?php

declare(strict_types=1);

$handle = popen('ls -l', 'r');
if ($handle === false) {
    throw new RuntimeException('Failed to open process');
}

// Read process output here...

$status = pclose($handle);

echo "Process exited with status: $status";

此代码打开一个列出文件的进程,然后使用 pclose 正确关闭它。在调用 pclose 之前,请务必检查 popen 是否成功。

关闭前读取进程输出

此示例演示了在关闭进程之前读取其输出。

read_before_close.php
<?php

declare(strict_types=1);

$handle = popen('date', 'r');
if ($handle === false) {
    throw new RuntimeException('Failed to open process');
}

$output = fread($handle, 4096);
$status = pclose($handle);

echo "Output: $output";
echo "Exit status: $status";

我们在关闭进程之前读取其输出。退出状态被捕获在 $status 中。在调用 pclose 之前,请务必读取所有输出。

使用 pclose 进行错误处理

这演示了如何对进程管道进行适当的错误处理。

error_handling.php
<?php

declare(strict_types=1);

$command = 'nonexistent-command 2>&1';
$handle = @popen($command, 'r');

if ($handle === false) {
    die("Failed to execute command: $command");
}

$output = stream_get_contents($handle);
$status = pclose($handle);

if ($status !== 0) {
    echo "Command failed with status $status\n";
    echo "Error output: $output";
} else {
    echo "Command succeeded: $output";
}

这展示了如何处理命令失败。我们捕获了输出和退出状态。2>&1 将 stderr 重定向到 stdout 以捕获错误。

写入进程

此示例演示了在关闭之前向进程写入数据。

write_process.php
<?php

declare(strict_types=1);

$handle = popen('grep "error" > errors.log', 'w');
if ($handle === false) {
    throw new RuntimeException('Failed to open process');
}

fwrite($handle, "error: file not found\n");
fwrite($handle, "warning: deprecated function\n");
fwrite($handle, "error: permission denied\n");

$status = pclose($handle);

echo "Grep process exited with status: $status";

我们打开一个用于写入的进程,向其发送数据,然后关闭它。该进程会过滤输入并写入文件。完成后务必关闭写入管道。

检查进程状态

此示例展示了如何解释进程的退出状态。

process_status.php
<?php

declare(strict_types=1);

function executeCommand(string $cmd): string
{
    $handle = popen($cmd . ' 2>&1', 'r');
    if ($handle === false) {
        throw new RuntimeException("Failed to execute: $cmd");
    }

    $output = stream_get_contents($handle);
    $status = pclose($handle);

    if ($status !== 0) {
        throw new RuntimeException(
            "Command failed with status $status: $output"
        );
    }

    return $output;
}

try {
    $result = executeCommand('ls -l /nonexistent');
    echo $result;
} catch (RuntimeException $e) {
    echo "Error: " . $e->getMessage();
}

这会将进程执行封装在一个具有适当错误处理的函数中。在关闭后检查退出状态。非零状态表示命令失败。

最佳实践

来源

PHP pclose 文档

本教程通过实际示例介绍了 PHP 的 pclose 函数,展示了其在不同场景下与进程管道的用法。

作者

我的名字是 Jan Bodnar,我是一名热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。至今,我已撰写了超过 1400 篇文章和 8 本电子书。我在教授编程方面有十多年的经验。

列出 所有 PHP 文件系统函数