【问题标题】:When file_put_contents fails if the directory is full, a file with size 0 is created. How to avoid that?如果目录已满,file_put_contents 失败,则会创建大小为 0 的文件。如何避免这种情况?
【发布时间】:2013-01-04 21:37:31
【问题描述】:

当 tmp 目录已满时,file_put_contents 返回 FALSE,但创建的文件大小为 0。file_put_contents 应该完成文件的创建,或者根本没有任何效果。例如:

$data = 'somedata';
$temp_name = '/tmp/myfile';
if (file_put_contents($temp_name, $data) === FALSE) {
    // the message print that the file could not be created.
    print 'The file could not be created.';
}

但是当我进入 tmp 目录时,我可以找到在该目录中创建的大小为 0 的文件“myfile”。这使得它难以维护。不应创建该文件,我希望看到一条消息或警告 tmp 目录已满。我错过了什么吗?这是正常的行为吗?

【问题讨论】:

  • 不是它的工作原理。您显然可以检测到故障。也许只是删除文件并发出警告?
  • 这个想法是 file_put_contents 不是原子的。要么完成工作,要么没有效果。
  • 我现在更了解您来自哪里。写入模式(标志)是否完全考虑在内,还是在所有模式中都会发生这种情况?我认为this 可能是相关的:“此函数与依次调用 fopen()、fwrite() 和 fclose() 以将数据写入文件相同。”
  • 我在 php 网站上提交了一个错误。见bugs.php.net/bug.php?id=63908

标签: php temporary-files


【解决方案1】:

您可能错过了,如果您执行错误消息,您也需要处理这种情况:

$data      = 'somedata';
$temp_name = '/tmp/myfile';

$success = file_put_contents($temp_name, $data);
if ($success === FALSE)
{
    $exists  = is_file($temp_name);
    if ($exists === FALSE) {
        print 'The file could not be created.';
    } else {
        print 'The file was created but '.
              'it could not be written to it without an error.';
    }
}

这也将允许您处理它,例如在写入临时文件的事务失败时进行清理,以将系统重置为之前的状态。

【讨论】:

  • 您不应将$successFALSE 进行比较,因为This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. - php.net/manual/en/function.file-put-contents.php
  • @vojtek:看到三个等号,它们不仅评估而且比较确切的类型?
  • 这个想法是如果 file_put_contents 失败,该文件不应该存在。我可以自己做到这一点,检查它是否存在,然后使用取消链接将其删除。但是,话又说回来,这里的问题是 file_put_contents 事务不是原子的,要么完全发生,要么没有效果。
  • @ALI: file_put_contents 做了很多事情。它只是不会在之后清理它,以防万一发生错误。是的,这可能是 PHP 的一个缺陷。您甚至可能想将此报告为错误。如果你这样做,请在这里留下一些参考。 bugs.php.net
  • @Ali:报告看起来不错,谢谢您的报告。拉斯穆斯已经回答了你,我会说他的论点没问题。该问题现已记录在案,因此现在应该更加清楚。还请与您的系统管理员交谈,盘片不应在 /temp 不被注意的情况下针对 0 运行,看看您的系统在那里做了什么。
【解决方案2】:

问题是 file_put_contents 不一定会返回布尔值,因此您的条件可能不合适,您可以尝试:

if(!file_put_contents($temp_name, $data)){
    print 'The file could not be created.';
    if(file_exists ($temp_name))
        unlink($temp_name);
}

【讨论】:

  • 没有真正描述问题,但假设相同的解决方案。
【解决方案3】:

嗨,兄弟,我找到了解决方案,

我知道它很旧,但它可能会帮助像我这样的其他人,

我搜索这个代码很久了。

$data      = 'somedata';
$temp_name = '/tmp/myfile';

$success = file_put_contents($temp_name, $data);
  if (!$success){
     $exists  = is_file($temp_name);
     if (!$exists) {
        print 'The file could not be created.';
     } else {
       print 'The file was created but '.
       'it could not be written to it without an error.';
     }
  }

【讨论】:

  • 在使用代码@hakre 并将 FALSE 更改为 ! 后效果很好
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 2014-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多