使用PHP和MySQL存储用户图像的最佳方式是什么?

使用PHP和MySQL存储用户图像的最佳方式是什么?,php,mysql,Php,Mysql,我想知道用PHP和MySQL存储用户上传头像等图片的最佳方式是什么?我应该从哪里开始?关于这方面有好文章吗?这里有一个在MySQL数据库中以二进制形式存储图像的示例。我不太确定这样做是否有好处。我会把它留给其他人评论 另一种方法是将图像的位置存储在列中,并查询它以进行引用 如果我是你,我会将图像保存在你的站点目录的某个地方,然后将图像链接保存在MySQL中,如果你真的想将其保存在数据库中,我会将其读入字符串,然后base64_encode()将其保存在数据库中 通过将它们存储在数据库中,您将面临

我想知道用PHP和MySQL存储用户上传头像等图片的最佳方式是什么?我应该从哪里开始?关于这方面有好文章吗?

这里有一个在MySQL数据库中以二进制形式存储图像的示例。我不太确定这样做是否有好处。我会把它留给其他人评论


另一种方法是将图像的位置存储在列中,并查询它以进行引用

如果我是你,我会将图像保存在你的站点目录的某个地方,然后将图像链接保存在MySQL中,如果你真的想将其保存在数据库中,我会将其读入字符串,然后base64_encode()将其保存在数据库中


通过将它们存储在数据库中,您将面临各种各样的小麻烦,您将不得不创建脚本以将它们回显,并且服务器和数据库负载将大大增加。如果我是你,我只会存储引用。

我建议用一个表来存储用户名、名字等用户数据。在该表中创建一个名为“avatar”的字段,您可以在其中存储文件引用

假设您的用户化身存储在:htdocs/images/avatars/
用户apikot将头像“avatar.jpg”存储在数据库中,在生成图像标记时,您可以编译以下url:“/htdocs/images/avatars/avatar.jpg”。

创建一个BLOB类型字段,并插入文件获取内容的结果($ImageFile)

“最佳”取决于您的目标

存储用户上传的图像的两种主要方法是将二进制内容作为BLOB放入数据库,或者将图像存储到驱动器的某个位置,并在数据库中输入一个条目,指示哪个图像属于哪个位置

将映像放置在数据库中的优点是不需要Web服务器上的任何类型的文件系统权限,并且如果要在多个Web服务器上为站点提供服务,则可以消除任何类型的同步问题。然而,随着时间的推移,它会使您的数据库变得巨大,如果您没有正确地设计表,它会完全破坏您的性能和可伸缩性

将图像作为文件存储在文件系统上还有一个额外的优点,即检索非常快速和高效,因为Web服务器非常擅长于服务静态文件

编辑以添加

如果决定在数据库中存储文件内容,绝对不要将其放在需要快速访问的表中。例如,如果您有一个“用户”表,几乎在每个页面视图上都会搜索该表,那么该表就不是放置文件内容的地方。相反,创建一个单独的“images”或“files”表,其中包含文件和相关的元信息


将每行大量字节放入表中会使该表的处理速度非常慢。您不希望在大量使用的表中出现这种情况。

图像确实应该存储在文件系统中,原因有两个:

  • 代理和If-Modified-Since-web请求:Apache可以为您处理If-Modified-Since-HTTP头并返回304响应,这是您可以获得的最佳性能。反向Squid代理和ISP上发布的代理将试图利用这一点

  • 病毒扫描:如果你允许上传任何文件,混蛋们会尝试上传可怕的东西,看看他们是否能破坏你的网站。想要对用户上传的内容运行ClamAV或类似程序来查看是否有问题,这并不是不合理的。如果你想扫描记录中的恶意软件,你不会想占用你的数据库

  • 模式简单性:如果允许文件上载,还需要添加有关MIME类型、文件大小、高度和宽度的元数据。如果文件本身与表中的MIME类型不匹配,则需要对表中的select进行编码,并将其流式传输到
    /usr/bin/file
    。使用
    shell\u exec(“/usr/bin/file/path/to/mumble”)
    要简单得多

  • 拇指钉法:用户图像上传可能需要拇指钉法,这通常比实际web请求异步完成容易得多。当一些好心的用户试图上传专业摄影师好友提供给他们的150MB photoshop文件,而您的apache实例在试图将ImageMagick库加载到web worker的内存空间中时出现OOM时,这真的不是一件有趣的事。对于apache工作人员来说,这确实无法扩展。在Apache之外创建一个工作队列/cron作业来处理此工作

  • 表损坏:哇,如果您的MySQL索引文件损坏,并且您需要在该表上执行脱机表修复,那么您真的不想破坏所有用户化身

  • 备份和恢复:您并不想用mysqldump锁定一个大表。使用rsync将为您节省大量时间并提供更大的灵活性。表通常一次恢复一个完整的表——表通常不会以较小的片段进行备份


在服务器上为每个用户创建一个新目录,用户id是目录的名称,并将用户的图像保存在其中。无论何时要显示用户的图像:

<img src="<path>/users_images/<user_id>/thumb.gif" />
/users\u images//thumb.gif/>

是的,我建议不要这样做,除非出于某种原因需要保护图像。通过这种方式,首先需要从数据库中提取图像,然后处理二进制文件。这将增加PHP服务器和MySQL服务器的负载。您的第二条建议更好;将图像存储在用户图像文件夹,可能使用uniqid()命名它们,然后在数据库中引用该相对URL。如果要使用数据库,这是一个非常好的主意。为了减轻图像表的负载,使用memcache缓存图像也会有所帮助。推论:如果您的文件