【发布时间】:2013-12-12 20:55:29
【问题描述】:
我们构建了一个 PHP 脚本来缓存服务器硬盘驱动器 (ext4) 上的图像(Debian Wheezy with SELinux、Apache、PHP 5.3.26)。
使用了类似下面的代码:
$data = "...";
$file = "cached_foo_1234.jpg";
if (!is_file($file)) file_put_contents($file, $data);
稍后在脚本中,打开同一个文件进行读取:
$content = file_get_contents($file);
尽管硬盘驱动器上的数据正确,但有时 $content 在文件写入文件系统时为空。函数 filesize() 显示相同的行为。
任何日志文件(审计、php 等)中都没有错误。将 clearstatcache() 放在 file_get_contents() 之上或在 file_put_contents() 中使用 LOCK_EX 锁定文件无济于事。该脚本以相同的文件名并行访问。 Apache 也无需 PHP 直接返回现有的缓存图像。
我猜文件锁定应该避免在写入文件时出现空返回。
为什么我们尝试从文件系统读取文件时得到零字节?
【问题讨论】:
-
运行网络服务器的用户是否有权 r/w/x 文件系统/目录?另外,该文件是否在 webroot 之外的某个位置?
-
file_get_contents不寻找咨询锁,同样服从它们。您需要同时锁定阅读器和作者。 -
用户拥有正确的权限。问题有时会发生,但并非总是如此。为什么文件大小的行为完全相同?
-
如果我在 PHP 之外处理以前存储的文件会怎样。假设我想在 ImageMagick 中阅读它。外部程序如何获取锁?
标签: php linux filesystems debian selinux