PHP file_exists 用目录代替名称?

PHP file_exists With Contents Instead of Name?

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

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

您可以使用 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 比较两个文件的方法:

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))

您可以将散列文件存储在由 \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");