2008-11-25 70 views
14

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

我宁愿个人使用file_exists()方法,因为这给了我一个简单的方法来回退到“默认”的头像,如果当前的头像不存在(还),它的简单实施代码明智。但是,我担心的是性能,因为这会在论坛阅读页面上针对每个用户显示的每个页面负载运行一次。所以我想知道,PHP中的file_exists()函数是否会导致在高流量情况下会导致重大性能下降的重大减速?

如果不是,很好。如果确实如此,您对备选方案有何看法以追踪用户上传的图像?谢谢!

PS:我可以看到的代码差异是文件检查版本允许文件进行交谈,而数据库表单相信数据库是准确的,不会检查。 (它只是一个传递给浏览器的url)

回答

12

除了其他海报的说法,file_exists()的结果被PHP自动缓存以提高性能。

但是,如果您已经从数据库中读取用户信息,那么您最好将信息存储在那里。如果用户只允许使用一个头像,则可以在“有头像”(1/0)的列中存储一位,然后使用与用户ID相同的文件名,并使用类似SELECT CONCAT(IF(has_avatar, id, 'default'), '.png') AS avatar FROM users

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

7

由于你的web服务器在显示你的网页的过程中已经做了很多(相当于)file_exists()操作,通过脚本运行可能不会产生可衡量的影响。 Web服务器可能会做至少:

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

这不考虑更多PHP可能会自己做的事情。

0

file_exists()本身并不慢。真正的问题是您的系统如何配置以及性能瓶颈在哪里。请记住,数据库也必须将事物存储在磁盘上,所以无论哪种方式都可能面临磁盘活动。另一方面,数据库和文件系统通常都有某种形式的透明缓存来优化重复访问。

你可以轻松地去任何一种方式,因为机会是你的性能瓶颈将在别处。我可以看到它是一个明显的选择的唯一的地方是,如果你在某种超额共享主机上存在大量的磁盘争用,但也许数据库访问在单独的集群上并且更快(反之亦然)。

0

在过去,我将图像元数据存储在数据库(包括其名称)中,以便我们可以生成有用的统计数据。更重要的是,存储图像数据(不是文件本身,只是元数据)是有利于改变。如果将来您需要“批准”图像,或者您希望在不删除文件的情况下将其删除,该怎么办?

根据“默认”头像...以及如果没有找到该用户的记录,只需使用默认的。

无论哪种方式,file_exists()或db,它不应该是担心的瓶颈。然而,一种解决方案更具可扩展性。

+0

你已经下了决心,我不知道为什么,这是一个很好的答案,我从来没有想过自己。 – 2008-11-25 08:57:04

+0

我已经采纳了一些追随者,downvote我做的一切。 – 2008-11-25 09:48:33

0

如果性能是您唯一的考虑因素,file_exists()将比数据库查找便宜得多。

毕竟这只是使用系统调用进行目录查找。脚本的第一次执行后,相关目录的大部分都将被缓存到存储器中,因此实际上涉及的I/O非常少,并且“file_exists()”是一种常见操作,因此它和底层系统调用将非常高效在任何常见的php/os组合上进行了优化。

正如约翰二世指出的那样。如果额外的功能和用户界面功能是一个优先事项,那么数据库将是一条路。

8

在实际的性能测试中,您会发现file_exists非常快。就像这样,在php中,当相同的url是“stat”的两倍时,第二个调用只是从php的内部统计缓存中提取。

而这只是在PHP运行范围。即使在运行之间,文件系统/ os也会倾向于将文件积极地放入文件系统缓存中,并且如果文件足够小,不仅文件存在测试会直接从内存中出来,而且整个文件也会存在。

下面是一些真实的数据来支持我的理论:

我只是在做Linux的命令行工具,一些性能测试“发现”和“xargs的”。在收益中,我对13000个文件进行了文件存在测试,每个文件存在100次测试,时间不到30秒,因此平均每秒测试43,000次测试,因此,如果您比较它的话,它需要将9除以8,但在真实世界的场景中,您需要很多次这样做才能看到显着的性能问题。

如果你有43 用户同时访问期间,第二,我想你会比它需要复制文件的存在状态的更多时间更大关注的时期你的网页,或者在平均情况下出现内存不足的情况。

1

至少在PHP4中,我发现对file_exists的调用肯定是在杀死我们的应用程序 - 它在库中非常深重,所以我们真的必须使用分析器才能找到它。删除电话增加了一些页面的计算十几次(电话重复发生)。

它可能会在PHP5中缓存file_exists,但至少在PHP4中不是这种情况。

现在,如果你不在循环中,很明显,file_exists不会是一个大问题。