用于处理用户图像上传的推荐架构

时间:2009-07-19 06:35:18

标签: php web-applications upload photo

过去,我以两种不同的方式处理用户图片上传:

  • 将图像数据保存在数据库表中,并通过PHP脚本加载
  • 上传图片,将其转换为jpeg,将其放入目录并通过HTML标记加载

第一个选项工作得相当好,但我必须对上传的图像保持相当大的限制。第二种选择是有效的,除了PHP的图像库通常会破坏文件转换(我认为可以通过使用ImageMagick来修复)。

我现在面临着第三次这样做,对于潜在的更大规模的用户。我已经计划在上传后使用ImageMagick对图像进行一些后期处理。我希望尽可能减少对图片上传的限制,甚至可能保留每个人上传的照片。

有时,数百个用户的照片上传将同时作为缩略图显示在屏幕上。将这些存储在数据库中并为每个数据库提取它们并通过PHP显示似乎不是一个好方法,但是将所有图像放入单个目录中也不是。

在这种情况下你的建议是什么?您是否使用上述选项之一,或者您有不同的解决方案?

7 个答案:

答案 0 :(得分:5)

  

将这些存储在数据库中并为每个数据库提取它们并通过PHP显示似乎不是一个好方法,但是将所有图像放入一个目录中也不会。

你可以采取混合方式。

将图像存储在文件夹中(根据您确定适合您的应用程序的任何方案)。存储数据库中每个图像的完整路径。

在后台作业中,制作图像的缩略图(比如ImageMagick),其文件名与图像本身略有不同(例如:在前面添加'thumb-'),但它们与真实图像一起存储。您可以在数据库中为每个图像添加一个字段,这意味着“我的缩略图已准备好,所以请将我包括在画廊中”。

当您收到图库请求时,使用数据库字段对图像组进行切片和切块,然后生成一段HTML,引用相应的缩略图和图像路径。


修改 当你需要处理大量请求时,Aaron F说的很重要。对图像/ sql数据进行分区是实现可伸缩性的良好途径。您需要查看应用程序中的访问模式,以确定分区所在的位置。您可以更快做的事情是为库缓存生成的HTML,以减少SQL负载。

答案 1 :(得分:2)

您引用的两个示例并未阐明最重要的部分:分区。

e.g。如果存储在数据库中,图像是否完全驻留在一个数据库服务器上的一个表中?或者表是多个服务器/集群的分区表?

e.g。如果存储在目录中,是否所有图像都驻留在一个硬盘上?或者图像是否根据用户登录名中的第一个字母映射到单独的[RAID]驱动器?

可扩展性需要一个好的分区方案。

就批量显示缩略图而言,您可能需要在此处进行一些预计算。即创建缩略图(可能通过同步作业,在图像上传后立即启动)并将它们放在专用服务器上。这就是Youtube为上传视频拍摄快照的方式。

答案 2 :(得分:1)

Imho,大卫的解决方案对大多数情况来说是最好的,但我会修改两个细节:

  

存储数据库中每个图像的完整路径。

我认为您不需要存储完整的路径,因为如果由于某种原因图像目录发生变化,这会使您的生活变得复杂一些。仅存储文件名就足够了。您始终可以直接在html中包含完整路径。

  

有生成图像的缩略图(比如ImageMagick),其文件名与图像本身略有不同,但与真实图像一起存储。

我更喜欢将缩略图放在不同的目录中,为您创建的每个拇指创建一个目录,并使用完全相同的文件名。我曾经在一个拥有数千个用户图像的网站上工作,我犯了将它们全部放在同一目录中的错误。该目录增长得如此之快,以至于无需等待几分钟即可打开此目录。

  

PHP的图像库通常会破坏文件转换

我建议在创建拇指的脚本中增加内存限制,特别是如果允许上传大(2mb +)文件。

您可以使用ini_set('memory_limit', '30M');执行此操作。当然,实际数字取决于您。 30M在缩略图重的网站上为我工作。

答案 3 :(得分:1)

几年前,我写了一个内部网图像存档,最终存储了大约34万次扫描和相对缩略图。谷歌搜索我发现没有硬性理由不将它们全部转储到一个目录中,只要你不要求底层操作系统进行文件夹列表。换句话说,调用ls / dir会挂起机器,但只是按文件名(从数据库中)检索单个图像文件就意味着没有性能损失。

该存档已经运行了几年,我可以确认它可以正常使用实际存储在文件夹中的60k以上图像。

我从来没有遇到过使用GD将内容转换为jpeg的任何问题,但对于那个特定的工作,我使用MagicWand作为帮助扩展的ImageMagick方式(主要是因为文档不错)。

答案 4 :(得分:0)

嗯用于创建缩略图,使用phpthumb ...它绝对是完美的...并且有一些额外的东西,但你可能不需要那些......它会自动创建一个本地缓存在你的文件系统上,所以它节省了资源......

我认为,混合方法可能是最具扩展性的,即在文件系统上存储文件和数据库中的文件位置......这样,您可以在文件中存储一些元数据(如创建者,标题,标签等) 。),并保持您的数据库小......此外,您可以将图像存储在任意位置(甚至在其他机器上等),这样您就可以轻松地分发所有有效负载......

格尔茨

back2dos

答案 5 :(得分:0)

如果你问我,我会使用Thumbnailer课程。

答案 6 :(得分:0)

这个问题是11年前提出的,它仍然非常相关,可以指导开发人员设计图像管理策略。我今天想加2美分,并指出可以使用的新技术。

我将根据获得的流量规模设计策略。让我解释以下情况。

案例1:本地或区域流量
主要流量来源:公司内部,特定省份/国家/地区
可预测性因子: 6-7 / 10。上线后改善
货币因素:免费或价格合理

在这种情况下,混合解决方案可能是最好的解决方案。在这里,您有以下选择

    1. 您可以创建自己的解决方案并在服务器上管理图像,并将其位置或文件名存储在数据库中。
    1. 第二个选项是使用图像托管网站,例如 postimage,cubupload,dropbox,google照片,imgbox,cubupload 。它们为您提供了访问图像的链接,并且/或者您可以将代码嵌入到Web应用程序或博客中。大多数都是免费的,并且存储空间有限。付费选项也非常实惠。
    1. 他们唯一要注意的是带宽。遇到很高的点击率时,您需要考虑到这一点。
    1. 您还可以使用选项1和2的混合方法。 back2dos,David-SkyMesh,djn,Alejandro Zuleta和Aaron Fi 的回答都很好。

案例2:全球流量
主要流量来源:全世界。
可预测性因子: 0/10。上线学习
金钱因素:昂贵

这是一个严重的用例,您必须注意两个最重要的因素,即可伸缩性和安全性。 Aaron Fi 指出了有关分区的问题,我建议采用以下方法。

    1. 使用图像CDN。这些是专用的CDN,您可以管理,调整大小,转换和保护图像。服务提供商提供了可伸缩性,因此您不必担心太多。一些服务提供商是 cloudimage,imgix,imagekit
    1. 您还可以使用云服务来管理您的图片,例如Amazon S3。服务提供商还在后端使用此类云服务。
    1. 此选项不便宜,并请检查每月流量数据并计算您的每月使用量。这是图像密集型网站的最佳选择。

希望这会有所帮助。