老问题,我要在这里添加一个答案。对于 php 5.3.8,is_file()(对于现有文件)要快一个数量级。对于不存在的文件,时间几乎相同。对于带有 eaccelerator 的 PHP 5.1,它们更接近一些。
PHP 5.3.8 w & w/o APC
time ratio (1000 iterations)
Array
(
[3."is_file('exists')"] => 1.00x (0.002305269241333)
[5."is_link('exists')"] => 1.21x (0.0027914047241211)
[7."stream_resolve_inclu"(exists)] => 2.79x (0.0064241886138916)
[1."file_exists('exists')"] => 13.35x (0.030781030654907)
[8."stream_resolve_inclu"(nonexists)] => 14.19x (0.032708406448364)
[4."is_file('nonexists)"] => 14.23x (0.032796382904053)
[6."is_link('nonexists)"] => 14.33x (0.033039808273315)
[2."file_exists('nonexists)"] => 14.77x (0.034039735794067)
)
带加速器的 PHP 5.1
time ratio (1000x)
Array
(
[3."is_file('exists')"] => 1.00x (0.000458002090454)
[5."is_link('exists')"] => 1.22x (0.000559568405151)
[6."is_link('nonexists')"] => 3.27x (0.00149989128113)
[4."is_file('nonexists')"] => 3.36x (0.00153875350952)
[2."file_exists('nonexists')"] => 3.92x (0.00179600715637)
[1."file_exists('exists"] => 4.22x (0.00193166732788)
)
有几个注意事项。
1) 并非所有“文件”都是文件,is_file() 测试 regular 文件,而不是符号链接。所以在 *nix 系统上,你不能只使用 is_file() ,除非你确定你只处理普通文件。对于上传等,这可能是一个公平的假设,或者如果服务器是基于 Windows 的,它实际上没有符号链接。否则,您必须测试is_file($file) || is_link($file)。
2) 如果文件丢失并且大致相等,所有方法的性能肯定会下降。
3) 最大的警告。所有方法都会缓存文件统计信息以加快查找速度,因此如果文件定期或快速更改、删除、重新出现、删除,则必须运行clearstatcache(); 以确保缓存中存在正确的文件存在信息。所以我测试了那些。我省略了所有文件名等。重要的是几乎所有时间都收敛,除了 stream_resolve_include,它的速度是 4 倍。同样,这个服务器上有加速器,所以 YMMV。
time ratio (1000x)
Array
(
[7."stream_resolve_inclu...;clearstatcache();"] => 1.00x (0.0066831111907959)
[1."file_exists(...........;clearstatcache();"] => 4.39x (0.029333114624023)
[3."is_file(................;clearstatcache();] => 4.55x (0.030423402786255)
[5."is_link(................;clearstatcache();] => 4.61x (0.030798196792603)
[4."is_file(................;clearstatcache();] => 4.89x (0.032709360122681)
[8."stream_resolve_inclu...;clearstatcache();"] => 4.90x (0.032740354537964)
[2."file_exists(...........;clearstatcache();"] => 4.92x (0.032855272293091)
[6."is_link(...............;clearstatcache();"] => 5.11x (0.034154653549194)
)
基本上,这个想法是,如果您 100% 确定它是一个文件,而不是符号链接或目录,并且很可能存在,那么使用is_file()。你会看到一定的收获。如果文件在任何时候都可能是文件或符号链接,那么失败的 is_file() 14x + is_link() 14x (is_file() || is_link()) 最终会整体慢 2 倍。如果文件的存在发生了很多变化,请使用 stream_resolve_include_path()。
所以这取决于你的使用场景。