我想知道使用PHP和MySQL存储用户上传图像的最佳方式是什么,如avatar等?我应该从哪里开始?有没有关于此的好文章?
答案 0 :(得分:16)
“最佳”取决于您的目标。
存储用户上传图像的两种主要方式是将二进制内容作为BLOB放入数据库,或者将图像存储到驱动器某处,并在数据库中放入一个条目,指示哪个图像属于哪里。
将图像放在数据库中的优点是不需要在Web服务器上使用任何类型的文件系统权限,并且如果您从多个Web服务器提供站点,则会删除任何类型的同步问题。但是,随着时间的推移,它会使您的数据库变得庞大,如果您没有正确设计表,那么它绝对会损害您的性能和可伸缩性。
将图像作为文件存储在文件系统上具有额外的优势,使得检索非常快速和高效,因为Web服务器非常擅长提供静态文件。
已编辑添加
如果您决定将文件内容存储在数据库中,绝对不要将其放在需要快速访问的表中。例如,如果您在几乎每个网页浏览中都搜索了“用户”表,则该表不放置文件内容的位置。而是创建一个单独的“图像”或“文件”表,其中包含文件和相关的元信息。
每行将大量字节放入表中会使该表使用起来非常慢。你不希望那些看起来很重要的表格中的那种东西。
答案 1 :(得分:13)
图像应该存储在文件系统中,原因有两个:
代理和If-Modified-自Web请求: Apache可以为您处理If-Modified-Since HTTP标头并返回304响应,这就是您可以获得的最佳性能。 ISP发布的反向Squid代理和代理将尝试利用此功能。
病毒扫描:如果您允许上传任何文件,那么混蛋会尝试上传可怕的内容,看看它们是否会破坏您的网站。想要针对用户上传运行ClamAV等来查看是否存在问题并非没有道理。如果要扫描恶意软件的记录,则不希望占用数据库。
架构简单性:如果允许文件上传,则还需要添加有关MIME类型,文件大小,高度和宽度的元数据。如果文件本身与表中的MIME类型不匹配,则需要对表中的select进行编码并将其流式传输到/usr/bin/file
。 shell_exec( "/usr/bin/file /path/to/mumble" )
可以简单得多。
Thumb-nailing:用户图片上传可能需要用拇指识别,这通常比实际的Web请求更容易完成。当一些有意义的用户尝试上传由他们的专业摄影师伙伴给他们的150MB photoshop文件时,真的不是很有趣,并且当你试图在Web工作者的内存空间中加载ImageMagick库时,你的apache实例会转到OOM。对于apache worker来说,这真的无法扩展。在Apache之外创建一个工作队列/ cron作业来处理这项工作。
表损坏:哇,如果您的MySQL索引文件被剔除并且您需要在该表上进行脱机表修复,那么您真的不想削弱所有用户头像。< / p>
备份和恢复:您真的不想用mysqldump锁定一个大表。使用rsync将为您节省大量时间并为您提供更大的灵活性。表通常会在整个表中恢复一次 - 表通常不会以较小的块备份。
答案 2 :(得分:3)
在服务器上为每个用户创建一个新目录,其中用户ID是目录的名称,并将用户的图像保存在其中。只要您想显示用户的图像:
<img src="<path>/users_images/<user_id>/thumb.gif" />
答案 3 :(得分:2)
如果我是你,我只是将图像保存在你的站点目录中的某个地方,然后将链接保存到MySQL中的图像,如果你真的想将它保存在数据库中,我会把它读成一个字符串然后base64_encode()然后将其保存在数据库中。
通过将它们存储在数据库中,您将面临各种各样的小问题,您将不得不创建脚本来回显它们,并且服务器和数据库负载将大大增加。如果我是你,我只会存储参考文献。
答案 4 :(得分:1)
我建议您使用一个表来存储用户数据,例如用户名,名字。在该表中创建一个名为“avatar”的字段,您可以在其中存储文件引用。
假设您的用户头像存储在:htdocs / images / avatars / 并且用户apikot将头像“avatar.jpg”再次存储在数据库中,然后在生成图像标记时可以编译以下URL:“/ htdocs / images / navata / avatar.jpg”。
答案 5 :(得分:0)
这是在MySQL数据库中以二进制形式存储图像的example。我不太确定是否有任何优势。我会留给别人发表评论。
您可以采用的另一种方法是将图像的位置存储在列中并查询它以进行引用。
答案 6 :(得分:0)
创建一个BLOB类型字段,并插入file_get_contents($ ImageFile)的结果