我如何在项目中保存图像?

时间:2009-04-08 09:35:09

标签: php asp.net image

这就是我想做的事............

我将让每个用户将多个图像上传到名为“pics”的文件夹中。 如果用户上传说“MyImage.jpg”,我会将其重命名为“MyImage_UserID.jpg”。 其中UserID当然是用户的唯一ID。 这样,当我查找用户的所有图像时,我将只查找以UserID结尾的图像名称。

这是错误的,还是有其他方法可以做到这一点?

我正在考虑将所有用户的所有图片放在1个文件夹中。

为每个用户创建一个文件夹是不是很愚蠢?

此外,该文件夹“pics”将如何保存?就像我不希望黑客添加或删除该文件夹中的图片。

任何输入?

6 个答案:

答案 0 :(得分:3)

如果每个用户都会有大量用户拥有大量图像,那么您的文件系统将开始窒息(前提是它不会崩溃无法处理大量文件)。

我建议为每个用户创建一个文件夹。不,这不是愚蠢的。

答案 1 :(得分:3)

在单个目录中存储太多文件可能会导致问题。不仅性能会受到某种程度的影响,但是朋友(比我的经验更多)告诉我,一些备份程序存在问题。

因此,当我必须存储数千张图像时,我总是创建256个子目录,并将文件存储在目录files/{id mod 256}/{myfile_id}.jpg

为了保护自己免受黑客攻击,有很多事情要做,没有什么是安全的(因为黑客很可能会尝试获取root权限,然后你的数据也不安全。)

1)所以...定期备份。期。
2)审核日志文件(谁当什么时候)。这不是安全本身,但可以帮助您发现安全漏洞并修复错误 3)相应地设置文件权限(在没有chroot的情况下在共享服务器上很重要)
4)仔细检查一个动作是否真的由合适的用户完成。猜猜网址一定不可能造成伤害。

如果你想让文件名和-paths保密,还有更多。例如可以不直接链接到图像,而是链接到提供该图像的脚本。在这种情况下,您可以将文件存储在webroot之外(此外,您更独立于文件名)(请参阅最后的代码)。

还有一个步骤是避免使用auto_increment id值来识别图像。更好地使用唯一的哈希(md5(mt_rand());)而不与数据库中的id和存储相关联(afaik youtube和flickr这样做)。

丑陋的php-pseudocode用于传递将是这样的:

<?php
  if (isset($_REQUEST['img'])) {
    $hash = $_REQUEST['img']);
    if (($res = getImageByHash($hash)) !== false) {
      list($id, $name, $mimetype) = $res;
      $path = '../images/' . ($id % 256) . '/' . $name;

      if (file_exists($path)) {
        header('Content-type: ' . $mimetype); // e.g. image/png
        readfile($path);
        exit();
      }
    }
  }

  // if any error happened, then 404 - it's dirty
  header("HTTP/1.0 404 Not Found");
  echo 'sorry, we couldn\'t find this image';
?>

getImageByHash()将查询数据库。 此解决方案较慢,因为网络服务器无法再直接提供图像。

和:我宁愿不将图像存储在数据库中。出口将变得巨大,备份是一种痛苦。

答案 2 :(得分:2)

将所有图像存储在一个目录中不是一个好选择。如果其中有许多节点,文件系统将会阻塞。

第一个选项是为每个用户提供自己的目录。但是如果你期望很多用户,最终会出现同样的问题。

人们通常想出的是:拆分userId:

+ 1
|- 11
|- 12
|- 1490
+ 2
|- 23
|- 240
...

但随后数据未通过目录结构均匀分布,导致其他问题。

最简单的解决方法是将userId从后面拆分:

+ 1
|- 231
|- 91
|- 1
+ 2
|- 6322
|- 342
...

但那里有更好的解决方案 另请参阅: How to store images in your filesystem 以获取更复杂的解决方案

接下来要担心的是:如何保持数据库和我的文件系统同步

  1. 创建数据库记录,标记为“未同步”
  2. 获取新插入记录的ID
  3. 将数据存储在文件系统中,并绑定到新插入的recordId
  4. 将记录标记为'synchronized'
  5. 删除东西是另一回事。

答案 3 :(得分:1)

帮助网站上的安全设置权限,以防止列出任何目录。因此,即使有人设法正确猜出文件夹的名称,他们也无法看到内容。

您还可以做其他事情 - 对网站安全性进行一些研究。

我同意Anton的观点,每个用户的目录是一个好主意。然后你甚至不必重命名图像。

答案 4 :(得分:0)

只需要一个单独的文件夹,你上传所有的图片,并有一个单独的表记录用户ID和imagefilename

上传图片时唯一需要检查的是是否存在相同的图像文件名,如果是,则重命名并相应保存

这是您选择在文件系统上保存图片


然而,请注意,这些天所有这些数据库都非常好。因此,即使您将图像直接保存在sql server中,可扩展性也不应该是一个问题。这样您就可以完全保护图像,无需重命名图像,管理文件系统等等

这里有很多人会争论这件事。但是请注意,sharepoint 2007使用sql server来保存文档,图像等等,如果你最终拥有大量用户,并且你需要负载平衡和后备,那么它在文件系统上很难实现(你将不得不依赖网络共享并复制您的网络共享以便退回)

但使用sql server实现的相同任务将是轻而易举的

答案 5 :(得分:0)

如果您不确定安全性,最好将图像保存在数据库中。你需要确定的一件事是,图片在那里需要太多的空间。你需要:

1)将em存储为JPEG,并将其他图像类型修改为JPEG

2)重新取样比实际需要的像素大的图片。

有一个特殊的组件AccessImagine,可以自动观看这个东西+给用户提供图像提交方法的自由。您可以在此处下载 - http://access.bukrek.net