PHP中的file_exist()是一个非常昂贵的操作吗?

时间:2008-11-25 07:55:52

标签: php performance

我正在为我正在设计的论坛引擎添加头像,我正在讨论是否要做一些简单的事情(论坛图片命名为.png)并使用PHP在显示之前检查文件是否存在,或者做一些更复杂(但不多)的事情,并使用数据库字段来包含要显示的图像的名称。

我更愿意亲自使用file_exists()方法,因为这样可以让我轻松地回归到“默认”虚拟形象,如果当前的虚拟形象尚未存在,并且它易于实现代码明智。但是,我担心性能,因为每个用户在论坛阅读页面上每页面显示一次就会运行一次。所以我想知道,PHP中的file_exists()函数会导致在高流量条件下导致显着性能下降的任何重大减速吗?

如果不是,那很好。如果是这样,您对跟踪用户上传图像的替代方案有何看法?谢谢!

PS:我可以看到的代码差异是文件检查版本允许文件进行通话,而数据库表单信任数据库是准确的并且无需检查。 (它只是一个传递给浏览器的URL。)

7 个答案:

答案 0 :(得分:12)

除了其他海报所说的内容之外,file_exists()的结果由PHP自动缓存以提高性能。

但是,如果您已经从数据库中读取用户信息,那么您也可以将信息存储在那里。如果用户只允许使用一个头像,则可以在“has avatar”(1/0)的列中存储一个位,然后使用与用户ID相同的文件名,并使用类似{{1}的内容}

您还可以考虑将实际图像作为BLOB存储在数据库中。将它放在自己的表中,而不是将其作为列附加到用户表。这样做的好处是它可以让您的论坛非常容易备份 - 您只需导出数据库。

答案 1 :(得分:8)

由于您的Web服务器在显示您的网页的过程中已经执行了大量(相当于)file_exists()操作,因此脚本运行的操作可能不会产生可测量的影响。 Web服务器可能至少会这样做:

  • 一个用于web根目录的每个子目录(用于检查存在和符号链接)
  • 一个用于检查Web根目录
  • 的每个子目录的.htaccess文件
  • 一个用于存在脚本的文件

这不是考虑更多的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组合上进行优化。

约翰二世指出。如果额外的功能和用户界面功能是优先考虑的话,那么数据库将是最佳选择。