peter844 Posted May 23, 2022 Share Posted May 23, 2022 (edited) Hello! I'm trying to understand why this script doesn't work, when I execute script simultaneously in same browser or browser tab, second script do not see the created file "/tmp/monkey.tmp" (php7.4-fpm + nginx, default config, opcache enabled) As soon as I used two different browsers, it works like expected, if I execute same script/URL simultaneously and one script with random data for example URL?_=monkey, it works like expected, problem is same URL in same browser, I dont understand why $tmpfile = '/tmp/monkey.tmp'; clearstatcache(); if(file_exists($tmpfile)) { die('file exist'); } else { file_put_contents($tmpfile, 'blabla'); } sleep(20); exit; Edited May 23, 2022 by peter844 Quote Link to comment https://forums.phpfreaks.com/topic/314830-why-file_exists-not-working/ Share on other sites More sharing options...
peter844 Posted May 23, 2022 Author Share Posted May 23, 2022 I don't understand why but it is caused by the Chrome browser cache, the response from the server does not contain any cache headers, when I disable browser cache, it works like expected Quote Link to comment https://forums.phpfreaks.com/topic/314830-why-file_exists-not-working/#findComment-1596570 Share on other sites More sharing options...
ginerjm Posted May 23, 2022 Share Posted May 23, 2022 All I see is you are trying to save a bit of text as a file. What I don't understand is the clearstatcache and the sleep(20). So what is NOT happening - the file is not created? How about turning on error checking and see if you get anything? Quote Link to comment https://forums.phpfreaks.com/topic/314830-why-file_exists-not-working/#findComment-1596575 Share on other sites More sharing options...
peter844 Posted May 23, 2022 Author Share Posted May 23, 2022 (edited) 2 hours ago, ginerjm said: All I see is you are trying to save a bit of text as a file. What I don't understand is the clearstatcache and the sleep(20). So what is NOT happening - the file is not created? How about turning on error checking and see if you get anything? Sleep is for debug, i need to execute scripts simultaneously in same browser, i need first script running when execute second script, clearstatcache clears file status cache, first script run create file and then sleep for 20 seconds, but second simultaneously script run (for example executed 3 seconds later) do not see the created file "/tmp/monkey.tmp"https://www.php.net/manual/en/function.sleep.phphttps://www.php.net/manual/en/function.clearstatcache Edited May 23, 2022 by peter844 Quote Link to comment https://forums.phpfreaks.com/topic/314830-why-file_exists-not-working/#findComment-1596583 Share on other sites More sharing options...
ginerjm Posted May 23, 2022 Share Posted May 23, 2022 And the question is why? Why do you need to post the same file at the same time? What are you really testing? I imagine also that the OS will run into a lock situation if you try and write the same file at the same time. This seems like a fruitless exercise unless you can give us some idea what your goal is. Quote Link to comment https://forums.phpfreaks.com/topic/314830-why-file_exists-not-working/#findComment-1596584 Share on other sites More sharing options...
peter844 Posted May 23, 2022 Author Share Posted May 23, 2022 (edited) 10 minutes ago, ginerjm said: And the question is why? Why do you need to post the same file at the same time? What are you really testing? I imagine also that the OS will run into a lock situation if you try and write the same file at the same time. This seems like a fruitless exercise unless you can give us some idea what your goal is. Prevent multiple execution of long running script, sorry, but it's clear from the code, you probably don't understand how the code I pasted here works, nevermind Edited May 23, 2022 by peter844 Quote Link to comment https://forums.phpfreaks.com/topic/314830-why-file_exists-not-working/#findComment-1596585 Share on other sites More sharing options...
ginerjm Posted May 23, 2022 Share Posted May 23, 2022 You control that by doing checking of the events you are trying to prevent from happening I suppose. What is it in your 'long-running' script that you don't want interference from another instance to occur? And just what is it that could be so long-running that 2 scripts would actually meet up at? Quote Link to comment https://forums.phpfreaks.com/topic/314830-why-file_exists-not-working/#findComment-1596586 Share on other sites More sharing options...
ginerjm Posted May 23, 2022 Share Posted May 23, 2022 OK - if you are worried about multiple users creating and removing the same filename why not use a random filename that only exists for that particular instance of the script? That way if there is more than one executing at the same time they won't interfere with each other when it comes to that filename usage. Quote Link to comment https://forums.phpfreaks.com/topic/314830-why-file_exists-not-working/#findComment-1596587 Share on other sites More sharing options...
kicken Posted May 23, 2022 Share Posted May 23, 2022 3 hours ago, ginerjm said: What is it in your 'long-running' script that you don't want interference from another instance to occur? And just what is it that could be so long-running that 2 scripts would actually meet up at? The intent is to essentially create a single instance script, similar to single-instance applications on the desktop. If you try and launch a second instance, it detects the first instance and either doesn't run or does something different. One possible scenario for this is if you have some cron job that runs every minute. If for some reason it takes longer than a minute to run, sometimes it's easier to just prevent the second instance from starting than to write the scripts in such a way that they don't cause problems. @peter844, assuming that is an accurate description of your goal, file_exists is not really the correct way to solve the problem. If you actually ran both scripts at the exact same moment, it's possible for them both to pass the file_exists test before either of them has a chance to actually create the file. A better solution is to use fopen with mode x flag to create the file. In this mode, fopen will fail if the file already exists, or create the file if it does not. Your script can use that to determine if the other instance is already running. Example: $lockFile = __DIR__.'/monkey.tmp'; $fp = @fopen($lockFile, 'x'); if (!$fp){ die('Script already running.'); } register_shutdown_function(function() use ($fp, $lockFile){ fclose($fp); unlink($lockFile); }); An even better solution, is to use flock to obtain an exclusive lock on the file. If the lock cannot be obtained then that means there is a script still running holding the lock. Example: $lockFile = __DIR__.'/monkey.tmp'; $fp = @fopen($lockFile, 'c'); if (!$fp){ die('Unable to access lock file'); } if (!flock($fp, LOCK_EX|LOCK_NB)){ die('Script is already running.'); } register_shutdown_function(function() use ($fp, $lockFile){ flock($fp, LOCK_UN); fclose($fp); unlink($lockFile); }); Quote Link to comment https://forums.phpfreaks.com/topic/314830-why-file_exists-not-working/#findComment-1596593 Share on other sites More sharing options...
peter844 Posted May 27, 2022 Author Share Posted May 27, 2022 (edited) @kicken Thanks for your reply, I know about the possibility of fopen and flock, I have the same problem with PHP semaphore, the problem is caused only by Google Chrome, when I disable the browser cache (in Google Chrome), it works like expected, even if there is no cache headers in the response and even when I insert a no-cache header into the response, when aj insert to response PHP's process ID, pid is not the same, it doesn't make sense for me another solutionhttps://www.php.net/manual/en/function.getmypid.php#112782 Edited May 27, 2022 by peter844 Quote Link to comment https://forums.phpfreaks.com/topic/314830-why-file_exists-not-working/#findComment-1596727 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.