我想知道如何使用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);
答案 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进行操作。