|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-06-29 20:08 UTC] stgrein at gmail dot com
Description:
------------
Hi,
functions which check if a file exists do report wrong results sometimes.
I did not find a special pattern, but maybe higher load is triggering it more.
The chance on my machine is around ~1% to hit the bug per function call.
I am using PHP v7.0.8 now but also had this bug on PHP v7.0.7. I did not test with earlier Versions.
Test script:
---------------
<?php
//check an existing file
$a = file_exists("/this/file/exists");
if($a === true) {
echo "File exists!"; //expected
} else {
echo "File does NOT exists!"; //bug hit
}
//expected output:
//File exists!
//chance to get this output is around 1% on my machine under load
//File does NOT exists!
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Nov 17 10:00:01 2025 UTC |
Here's a cmd command to repeat the test 10k times: (for /l %i in (1,1,10000) do php -r "var_dump(file_exists('/this/file/exists'));") | find /c "true" Naturally it needs to be run from where you have PHP installed (or give the path to php.exe) and you need to change the /this/file/exists path. If you run that, does it show 10000 or something less? What if the system and/or disk is under load? Also, if you're getting this behavior with regular PHP code, are you potentially creating that file first? Because PHP will cache stat information during execution; if you are creating the file then use clearstatcache() before re-testing for the presence of the file. http://php.net/manual/en/function.clearstatcache.php Also, testing with PHP 5.5 or 5.6 would be appreciated.Try a similar test with Apache: /test.php: <?php var_dump(file_exists('/this/file/exists')); /loop.php: <?php $c = 0; for ($i=1; $i<=10000; $i++) { if (strpos(file_get_contents("http://localhost/test.php"), "true")) $c++; } echo $c, "/10000";Thank you for the test case. I had to add a set_time_limit(0); to the loop.php Then I got: 10000/10000 I modified test.php a little bit to use a relative path and I had to start it in 5 different Browser Tabs in Parallel: /test.php: <?php var_dump(file_exists('relative\path\to\an\existing\file.php')); Now I got: Tab1: 8248/10000 Tab2: 7762/10000 Tab3: 7685/10000 Tab4: 7726/10000 Tab5: 7783/10000 This was reproduceable if i refreshed (F5) my actual website in a sixth tab. Conclusion: While using absolute paths everything is working, but if using relative paths there is a chance to fail. These are my loaded modules: [PHP Modules] bcmath bz2 calendar Core ctype curl date dom exif filter gd gettext hash iconv imagick intl json ldap libxml mbstring mcrypt mysqli mysqlnd OAuth openssl pcre PDO pdo_mysql pdo_sqlsrv Phar Reflection session SimpleXML soap sockets SPL sqlsrv standard tokenizer wddx xdebug xml xmlreader xmlrpc xmlwriter xsl Zend OPcache zip zlib [Zend Modules] Xdebug Zend OPcache I suspect the imagick extension (I tested with different versions but also with the very newest one) to cause this behavior.