问题
Update
As this.lau_ commented, it seems the problem is that no code is running at all on the server when the first file is running. I guess some configuration only allows one script to be run at once - or only one script per "user".
Now I will investigate what can be causing that behaviour on the server. Thank you everyone for your help!
.
Original question
I've got two PHP scripts, on separate files:
/* The first file contains */
for($i = 0; $i < 10000; $i++){
$w = fopen($progress_file, "w");
fwrite($w, $i);
fclose($w);
}
/* The second file contains */
$f = fopen($progress_file, "r");
$progress_read = fread($f, filesize($progress_file));
fclose($f);
echo $progress_read !== false ? $progress_read : 0;
As you can see, I make a loop so I have time to refresh second file and wait for it to give the the number it's written in that moment.
I know that, when doing fopen($file, "w");
I'm truncating that file, so it won't give me (sometimes) the number it should give, and it will give 0. However, it should echo something, as I check if the file has been able to be read and, otherwise, echo "0".
Instead, I get the second file waiting (shown as loading) without echoing nothing until the first file gets completed the whole loop (so I always end up with "9999" on the second file).
I've tried changing the modes of fopen()
with no luck, as well as making the fopen()
and fclose()
outside the loop. No luck neither. I've also tried changing the fopen-fread-fclose thing with file_get_contents()
and other functions and nothing has worked.
Also, fflush()
, ob_flush()
and flush()
haven't made any difference.
As I said, the file gets written (if I open it with a text editor, I see the content changes) and even if it wouldn't, it should echo "0".
Why is the second file waiting, without echoing nothing, until the first loop ends?
Thank you.
回答1:
So for the use of for loops in PHP you must know it will do the thing in the loop till the condition in the for loop is false. So taken your code the forloop wil at first run take:
for(i=0; i<1000; i++){...}
And this returns true so it go in the forloop and execute every thing you want. At the end it will execute i++ en will go back to the evaluation of the for loop so :
for(i=1 i<1000; i++){...}
and again this is true. Well this go on till i = 9999. So in the meanwhile it opend and closed the file 9999 times en wrote the correspondence number in this file. As you hopefully can see is that your code is locked at that forloop and wont continue to go further than when the forloop is evaluated false.
You can make this work is you make you forloop like it is now but when you close the file in the forloop you call a method from the other file like:
for($i = 0; $i < 10000; $i++){
$w = fopen($progress_file, "w");
fwrite($w, $i);
fclose($w);
doSomthingWithFile($filename);
}
And on the other side:
doSomthingWithFile($filename){
$f = fopen($filename, "r");
$progress_read = fread($f, filesize($filename));
fclose($f);
echo $progress_read !== false ? $progress_read : 0;
}
I hope this make somethings clear.
回答2:
The second script does not wait. You either need to use
file_put_contents($filename,$str,LOCK_EX);
to force files waiting or you need to implement some loop with delay.
You could add a loop on the begin of your script to start test at same time like this:
echo "flock test ".time()."<br>";
$constant_time = 1570612500;
while ( time()<$constant_time )
{
usleep(500);
}
Where $constant_time is time when you wish to start both scripts in the same time. Give it current time shown by echo + 20 seconds, then upload it on server, then run the scripts (you need to do that before the time elapsed. This way both scripts will start at the same time.
PS: I originally searched answer if fread can wait when LOC_EX is set and this question came out.
来源:https://stackoverflow.com/questions/40655297/php-fread-waiting-until-another-fwrite-script-ends