【问题标题】:How should I format user uploaded pictures' filenames?我应该如何格式化用户上传图片的文件名?
【发布时间】:2010-02-05 23:29:06
【问题描述】:

我的网站处理用户上传的图片。我对我的图片文件名应该包含什么有点矛盾。我担心简单的可扩展性和可能的​​安全性?也许有人在处理同样的事情并且可以告诉我他们在他们的网站上的用途?

目前,我的文件名约定是

{pictureId}_{userId}_{salt}_{variant}.{fileExt}

salt 是在服务器端生成的令牌(不知道为什么我决定把它放在这里,也许是出于安全目的我不知道),variant 类似于t,它表示它是缩略图。所以它看起来像

12332_22_hb8324jk_t.jpg

请指教,谢谢。

【问题讨论】:

  • 你如何处理文件名?解析它以找出用户等?
  • 请记住,服务器文件系统上的文件名与 URL 之间没有任何直接关系。
  • 只是试图保持文件系统井井有条。并且将来可能能够解析它。

标签: naming-conventions filenames image


【解决方案1】:

除了之前的 cmets,您可能还需要考虑为您的文件创建一个目录层次结构。根据卷和托管文件的特定操作系统,您可以轻松地达到在单个目录中拥有大量文件的程度。每个文件夹允许的文件数量可能有限制。如果您需要对文件进行任何手动 QA 或维护,这可能会出现问题(尤其是如果此类维护没有编写脚本)。

我曾经参与过一个包含大量图像的项目。除了每个文件的文件名,我们决定在我们的数据库中记录一个子路径。我们的文件夹名称如下所示:

a/e/2/f/9
3/3/2/b/7

本质上,我们创建了 5 深的文件夹,其中一个十六进制值作为文件夹名称。深度可能过度,但有效。我想这可能导致我们达到了卷上文件夹数量的限制(不确定是否存在这样的限制)。

除了路径之外,我还会考虑存储一个驱动器(假设您有一堆磁盘用于存储)。通过这种方式,您可以移动图像,然后在移动过程中更新您的数据库(假设您有一个)。

【讨论】:

  • 啊酷,非常有见地。我可能会考虑这样做,但在我的网站变得足够大(如果有的话)之前这样做可能还为时过早
  • 谢谢!为了清楚起见,我们只会根据需要生成目录。所以我们有一些代码会在文件上传时生成一个随机子路径,检查代表子路径的目录是否存在(树中的 5 个目录:例如 4/3/f/a/a),以及如果目录不存在,则创建目录。或者,您可以根据用户 ID 创建目录,或者通过这两种方法的某种组合。
【解决方案2】:

我的 2 便士值;我想说的是,在这个问题上,可扩展性和安全性之间存在一些冲突。

  1. 如果您有真正的安全问题,那么您根本不应该依赖目标图像的文件名:这只是通过混淆来实现安全性 - 最终有人可能会猜到名称。[即使您有盐的想法,这更难]

相反,您至少应该有一个登录机制来在客户端和服务器之间创建会话,以确保您只有在经过身份验证后才能访问内容:即使这样,内容也是可嗅探的:如果安全性确实是一个问题,那么我会说你必须使用 SSL。

  1. 关于可扩展性:我建议您实际上确实为您的图像提供序列号:并将它们存储在每个(例如)500 个图像的“箱”中。当你填满一个垃圾箱时,创建一个新垃圾箱。将 bin (min-image-id, max-image id) 信息存储在一个 DB 表中,将图像编号存储在另一个数据库表中:然后您可以比较便宜地从特定图像的 id 找到哪个 bin。这是存储大量文档/图像的一种相当常见的解决方案。

然后您可以将您的 URL 映射到 bin+image id:但是为了避免 Jason Williams 指出的问题(顺序编号,便于探测),您确实应该像第 1 点那样单独解决安全问题。

【讨论】:

  • 感谢大家的所有回复。我对自己的问题有了很多见解,但这为我提供了寻求解决方案的最多信息。
【解决方案3】:

您可能想考虑用(例如)减号替换下划线。 (下划线在 SQL 中用作通配符,因此有一天您可能会在 LIKE 比较中遇到麻烦)。 (当然,下划线只是邪恶的 :-)

您的示例看起来像是在避免使用空格和大写字符 - 好举措。我会将所有内容保持小写并使用不区分大小写的比较来消除不同文件系统的任何潜在的区分大小写问题。

只要您可以处理用户 ID、图片 ID 和类型 ID 中的任意位数,可扩展性应该没问题。使用此方案,您不太可能达到任何文件名长度限制。

如果您使用顺序 ID,安全性可能会成为问题,因为有人可能会调整数字并请求他们不应该访问的图片 - 但盐应该使某人几乎不可能猜出正确的文件名另一张照片。如果用户无法以任何方式查看/访问内部文件名,这可能是不必要的措施。

【讨论】:

  • 感谢您的回复。我可能会考虑使用破折号,但是我的脚本文件(user_profile.php)使用下划线,我想这不会相关吗?讨论停止后将接受答案
【解决方案4】:

首先要做的是设置一个目录结构来模拟您的用例。在您的情况下,您有一个上传图片的用户。您可能会有这样的目录结构(可能在某处的网络共享上):

-图片 -用户ID1 -PictureID1~^~Variant.jpg -PictureID2~^~Variant.jpg -用户ID2 -PictureID1~^~Variant.jpg -PictureID2~^~Variant.jpg

图片 - 只是下面的根目录。

UserID - 是数据库用户 ID。

PictureID 只是数据库中的图片 ID(假设您在数据库中记录了每张上传图片的文件名。)

~^~ - 这只是一个分隔符。您可以使用一个字符或 X 字符序列。我喜欢三个字符,因为它可以通过拆分功能轻松处理,并且在文件名中很容易区分。

有时我喜欢在文件名 .256.jpg 或 .1024.jpg 中添加图片的大小。

无论如何,这一切都取决于您的用例。最重要的是正确设置目录结构。这样可以更轻松地访问/提供和管理图片。

您可以将所需的任何其他信息添加到文件名中,只要它不超过系统上的最大文件名长度即可。

【讨论】:

    猜你喜欢
    • 2014-01-13
    • 2021-10-09
    • 2011-09-09
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多