我正在为我正在设计的论坛引擎添加头像,我正在讨论是否要做一些简单的事情(论坛图片命名为.png)并使用PHP在显示之前检查文件是否存在,或者做一些更复杂(但不多)的事情,并使用数据库字段来包含要显示的图像的名称。
我更愿意亲自使用file_exists()方法,因为这样可以让我轻松地回归到“默认”虚拟形象,如果当前的虚拟形象尚未存在,并且它易于实现代码明智。但是,我担心性能,因为每个用户在论坛阅读页面上每页面显示一次就会运行一次。所以我想知道,PHP中的file_exists()函数会导致在高流量条件下导致显着性能下降的任何重大减速吗?
如果不是,那很好。如果是这样,您对跟踪用户上传图像的替代方案有何看法?谢谢!
PS:我可以看到的代码差异是文件检查版本允许文件进行通话,而数据库表单信任数据库是准确的并且无需检查。 (它只是一个传递给浏览器的URL。)
答案 0 :(得分:12)
除了其他海报所说的内容之外,file_exists()的结果由PHP自动缓存以提高性能。
但是,如果您已经从数据库中读取用户信息,那么您也可以将信息存储在那里。如果用户只允许使用一个头像,则可以在“has avatar”(1/0)的列中存储一个位,然后使用与用户ID相同的文件名,并使用类似{{1}的内容}
您还可以考虑将实际图像作为BLOB存储在数据库中。将它放在自己的表中,而不是将其作为列附加到用户表。这样做的好处是它可以让您的论坛非常容易备份 - 您只需导出数据库。
答案 1 :(得分:8)
由于您的Web服务器在显示您的网页的过程中已经执行了大量(相当于)file_exists()操作,因此脚本运行的操作可能不会产生可测量的影响。 Web服务器可能至少会这样做:
这不是考虑更多的PHP可能会自己做的。
答案 2 :(得分:8)
在实际的性能测试中,您会发现file_exists非常快。实际上,在php中,当同一个url是“stat”'d两次时,第二个调用就是从php的内部stat缓存中提取的。
这只是在php运行范围内。即使在运行之间,文件系统/ os也会倾向于将文件积极地放入文件系统缓存中,如果文件足够小,不仅文件存在测试直接从内存中出来,而且整个文件也是如此。
这是支持我理论的一些真实数据:
我刚刚对linux命令行实用程序“find”和“xargs”进行了一些性能测试。在收益中,我在13000个文件上执行了一个文件存在测试,每次100次,在30秒内,这样每秒平均43,000次静态测试,所以当然,如果你比较它,那么它的速度很慢。它需要将9除以8,但在现实世界中,您需要多次执行糟糕以查看显着的性能问题。
如果您有43个千用户同时访问您的网页,在一秒钟内,我认为您将比复制存在状态所需的时间更大在平均情况下,文件或多或少的内存不足。
答案 3 :(得分:2)
至少在PHP4中,我发现调用file_exists肯定会杀死我们的应用程序 - 它在库中非常重复,所以我们真的不得不使用分析器来查找它。删除呼叫增加了一些页面的计算十几次(呼叫是重复的)。
在PHP5中它们可能会缓存file_exists,但至少在PHP4中并非如此。
现在,如果你不在循环中,很明显,file_exists不会是一个大问题。
答案 4 :(得分:0)
file_exists()本身并不慢。真正的问题是如何配置系统以及性能瓶颈在哪里。请记住,数据库也必须将内容存储在磁盘上,因此无论哪种方式,您都可能面临磁盘活动。另一方面,数据库和文件系统通常都采用某种形式的透明缓存来优化重复访问。
你可以轻松地走向任何一种方式,因为你的性能瓶颈很可能会在其他地方出现。我可以看到它是一个显而易见的选择的唯一地方是,如果你在某种超级共享主机上有大量的磁盘争用,但可能数据库访问是在一个单独的集群上更快(反之亦然)。
答案 5 :(得分:0)
过去我将图像元数据存储在数据库中(包括其名称),以便我们可以生成有用的统计数据。更重要的是,存储图像数据(不是文件本身,只是元数据)有助于改变。如果您将来需要“批准”图像,或者想删除它而不删除文件,该怎么办?
根据“默认”头像...如果找不到该用户的记录,只需使用默认值。
无论哪种方式,file_exists()或db,它都不应该成为担心的瓶颈。然而,一种解决方案更具扩展性。
答案 6 :(得分:0)
如果性能是您唯一的考虑因素,那么file_exists()将比数据库查找便宜得多。
毕竟这只是使用系统调用的目录查找。在第一次执行脚本之后,大多数相关目录将被缓存在存储中,因此涉及的实际I / O非常少,并且“file_exists()”是一种常见的操作,它和底层系统调用将是高度的在任何常见的php / os组合上进行优化。
约翰二世指出。如果额外的功能和用户界面功能是优先考虑的话,那么数据库将是最佳选择。