【问题标题】:PHP's file_get_contents() sometimes returns zero bytes / falsePHP file_get_contents() 有时返回零字节/假
【发布时间】: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


【解决方案1】:

遇到这个问题,发现是文件名中包含不允许的字符导致无效。

要删除无效的文件名字符,请使用:

$bad = array_merge(
    array_map('chr', range(0,31)),
    array("<", ">", ":", '"', "/", "\\", "|", "?", "*"));
$result = str_replace($bad, "", $filename);

Filename practice

【讨论】:

    【解决方案2】:

    使用 curl,并检查是否忽略以验证 SSL: curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

    【讨论】:

      猜你喜欢
      • 2013-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-24
      • 1970-01-01
      • 2014-09-14
      • 1970-01-01
      • 2010-10-28
      相关资源
      最近更新 更多