PHP file_get_contents timeout"本地文件" (NFS /安装)

时间:2016-11-10 12:10:51

标签: php file-io nfs php-ini php-socket

我想知道如何使用file_get_content(不是HTTP uri)在本地文件上设置超时, 有时NFS挂载分区非常慢,我宁愿在超时后放弃(例如5s),

file_get_contents("/mnt/photo/photo.jpg");

我阅读了其他类似问题的答案,但我想解决方案只适用于HTTP,而不适用于本地文件:

$ctx = stream_context_create(array('http'=>array('timeout' => 1200)));

我还认为这个解决方案不适合我,也适用于Web,对吧?

ini_set('default_socket_timeout', 900);

2 个答案:

答案 0 :(得分:1)

您可以使用stream_set_blocking以非阻塞模式设置流,并尝试读取文件直到超时。类似的东西:

function readReallyBigFile($path, $timeoutSeconds = 5) {
    if (false === $stream = fopen($path, "r")) {
        throw new \RuntimeException('Cannot open file');
    }

    stream_set_blocking($stream, 0);

    $timeout = time();

    $contents = '';
    while (!feof($stream)) {
        $contents .= fread($stream, 8192);
        if ((time() > $timeout + $timeoutSeconds)) {
            throw new \RuntimeException('Timeout reached out');
        }
    }

    fclose($stream);

    return $contents;
}

$img = readReallyBigFile('/mnt/photo/photo.jpg');

答案 1 :(得分:1)

我担心,您无法通过PHP控制NFS超时,因为NFS协议选项仅通过挂载选项进行控制。 PHP不知道文件是在NFS上还是在本地硬盘上。我相信,有一些方法可以确定文件在NFS上的事实,但它不会让我们控制超时。

NFS中有两种类型的超时:次要主要。如果在安装选项(timeo)中指定的超时内未收到服务器的确认,则会发生次要超时。然后重试操作,超时加倍。超时间隔达到60秒时发生主要超时。接下来会发生什么取决于其他选择。

默认情况下,原始超时加倍,重试会无休止地继续。据说卷是硬安装的(默认情况下hard选项打开)。如果使用soft选项装入卷,则主要超时将导致I / O错误。你应该考虑软安装。但请注意,默认超时仅为 7 (0.7秒),这对于软安装来说可能略微过小。您应该估计可能的等待时间,并相应地调整timeo选项。

另一个有趣的选项是intr,它应该允许中断挂起的NFS操作。但是,在内核版本2.6.25之后不推荐使用此选项。只有SIGKILL才能中断NFS操作。您可能希望使用fork()函数实现监视程序进程。子进程可以运行NFS操作,父进程可以在一段时间后kill进行操作。