PHP file_exists 内容而不是名称?

Posted

技术标签:

【中文标题】PHP file_exists 内容而不是名称?【英文标题】:PHP file_exists With Contents Instead of Name? 【发布时间】:2018-10-05 08:02:42 【问题描述】:

是否有一个 php 内置函数,其作用类似于 file_exists,但给出的是文件内容而不是文件名?

我需要这个,因为我有一个人们可以上传图片的网站。图像存储在一个文件中,其名称由我的程序 (image_0.png image_1.png image_2.png image_3.png image_4.png ...) 确定。我不希望我的网站有多个具有相同内容的图像。如果多人在互联网上找到一张图片并且所有人都将其上传到我的网站,则可能会发生这种情况。我想检查是否已经有一个包含上传文件内容的文件以保存在存储空间中。

【问题讨论】:

【参考方案1】:

您可以将散列文件存储在由\n 分隔的.txt 文件中,以便您可以使用以下函数:

function content_exists($file)
  $file = hash('sha256', file_get_contents($file));
  $files = explode("\n", rtrim(file_get_contents('files.txt')));
  if(in_array($file, $files))
    return true;
  
  else
    return false;
  

然后您可以使用它来确定是否应该保存文件,如下所示:

if(content_exists($_FILES['file']['tmp_name']))
  // upload

else
  // do not upload

只需确保在存储文件IS时,您使用以下代码行:

file_put_contents('files.txt', hash('sha256', file_get_contents($file)) . "\n");

【讨论】:

【参考方案2】:

这是您可以使用 PHP 准确比较两个文件的方法:

function compareFiles($file_a, $file_b)

    if (filesize($file_a) == filesize($file_b))
    
        $fp_a = fopen($file_a, 'rb');
        $fp_b = fopen($file_b, 'rb');

        while (($b = fread($fp_a, 4096)) !== false)
        
            $b_b = fread($fp_b, 4096);
            if ($b !== $b_b)
            
                fclose($fp_a);
                fclose($fp_b);
                return false;
            
        

        fclose($fp_a);
        fclose($fp_b);

        return true;
    

    return false;

如果你保留你接受的每个文件的 sha1 总和,你可以简单地:

if ($known_sha1 == sha1_file($new_file))

【讨论】:

是的,但是您如何查看具有该内容的文件是否已经存在,而没有 file_b 的名称,您是否只需要在我的答案中使用 while 循环来遍历所有文件? 是的,恐怕。比较 sha 总和是更快的方法,您可以在文件名中包含大小参考,并仅检查类似大小的。【参考方案3】:

您可以使用 while 循环来查看所有文件的内容。这在下面的示例中显示:

function content_exists($file)
  $image = file_get_contents($file);
  $counter = 0;
  while(file_exists('image_' . $counter . '.png'))
    $check = file_get_contents('image_' . $counter . '.png');
    if($image === $check)
      return true;
    
    else
      $counter ++;
    
  
  return false;

上述函数查看所有文件并检查给定图像是否与已存储的图像匹配。如果图像已经存在,则返回true,如果图像不存在,则返回false。下面是如何使用此功能的示例:

if(content_exists($_FILES['file']['tmp_name']))
  // upload

else
  // do not upload

【讨论】:

虽然期望二次行为。 有没有更快的方法可以推荐? 存储哈希值并首先比较它们。但请务必验证误报。 所以当上传图片时,对内容进行哈希处理,然后比较其他存储的哈希值,如果相同的哈希值不存在则上传。对吗? 如果它是一个带有示例的答案,我很乐意接受这个答案:),我知道你的意思,但我不想回答你的想法。

以上是关于PHP file_exists 内容而不是名称?的主要内容,如果未能解决你的问题,请参考以下文章

PHP file_exists 目录

file_exists() 在 while 循环内的 php5 中不起作用

file_get_contents 加上 file_exists (在被调用的文件内)

PHP 中的 file_exist() 是一项非常昂贵的操作吗?

php中file_exists的CPU负载

file_exists() 的 PHP 不区分大小写版本