How does PHP "file_get_contents()" function handles the request if a given file is being written? Does it wait until the writing process is finished and then read the file, or, does it just fail to read the file?
Does "file_get_contents()" function use "flock()" function by default?
I did some tests and, indeed, "file_get_contents()" does not make use of "flock()" and there is no way to use "LOCK_SH" flag as an alternative!
If a file is being written, "file_get_contents()" does not wait in queue, it reads the file then it returns an empty string!
I wrote "flock_file_get_contents()" function as an alternative, if a file is being written, it waits in queue until the write process is over then it reads the file!
Better solutions are always welcome!
[OBS]:
[Edited]:
<?php
$Overwrite_Sleep = 10; //seconds
$flock_GFC_Sleep = 2; //seconds
$File = basename($_SERVER['SCRIPT_FILENAME'], '.php') . ".txt";
if (isset($_POST["Request"])){
if($_POST["Request"] == "Get_File_Content"){echo file_get_contents($File);
}else if ($_POST["Request"] == "flock_Get_File_Content"){echo flock_file_get_contents($File);
}else{
flock_file_put_contents($File, function($F_P){
$File_Content = file_get_contents($F_P);
$File_Content = str_replace("O", "A", $File_Content);
$File_Content = str_replace("p", "t", $File_Content);
$File_Content = str_replace("0", "", $File_Content);
//the below is basically what "file_put_contents()" does, except the "sleep()" part
$File_Handle = fopen($F_P, 'w');
fwrite($File_Handle, $File_Content . sleep($GLOBALS["Overwrite_Sleep"])); //the write process takes some time to finish
fclose($File_Handle);
}, $Return_Message);
echo ($Return_Message == 1) ? "File Overwritten" : "Failed: " . $Return_Message;
}
return;
}
file_put_contents($File, "Oops");
function flock_file_get_contents($File){ //______________________________________________
$File_Handle = fopen("$File", "r");
if(flock($File_Handle, LOCK_SH)){ //on success, this script execution waits here until older scripts in queue unlock the file
$File_Content = file_get_contents($File);
sleep($GLOBALS["flock_GFC_Sleep"]);
flock($File_Handle, LOCK_UN); //unlock the file so new scripts in queue can continue execution
}else{$File_Content = ["flock"=>"Fail"];}
fclose($File_Handle);
return $File_Content;
}
function flock_file_put_contents($File, $Do_This, &$Return_Var = ""){ //__________________________________________
$File_Handle = fopen($File, 'r');
if (flock($File_Handle, LOCK_EX)) { //on success, this script execution waits here until older scripts in queue unlock the file
$Do_This($File);
$Return_Message = 1;
flock($File_Handle, LOCK_UN); //unlock the file so new scripts in queue can continue execution
}else{$Return_Message = "flock() Failed";}
fclose($File_Handle);
$Return_Var = $Return_Message;
return $Return_Message;
}
?>
<!DOCTYPE html>
<div style=" float:left;">
<input type="button" value="Overwrite File (Wait <?php echo $Overwrite_Sleep ?> Seconds)" onclick='Test("Overwrite_File", this, Call_Count++)'>
<br>
<div id="Response_Overwrite"></div>
</div>
<div style=" float:left; margin-left: 50px; ">
<input type="button" value="file_get_contents()" onclick='Test("Get_File_Content", this, Call_Count++)'>
<br>
<div id="Response_Get_Content"></div>
</div>
<div style=" float:left; margin-left: 50px; ">
<input type="button" value="flock_file_get_contents() - Wait <?php echo $flock_GFC_Sleep ?> seconds" onclick='Test("flock_Get_File_Content", this, Call_Count++)'>
<br>
<div id="Response_flock_Get_Content"></div>
</div>
<br style=" clear: both;"><br><br>
<?php
echo $_SERVER['SCRIPT_FILENAME'] . "<br><br>";
echo __FILE__ . "<br><br>";
echo basename(__FILE__) . "<br><br>";
echo basename(__FILE__, '.php') . "<br><br>";
echo basename($_SERVER['SCRIPT_FILENAME']) . "<br><br>";
echo basename($_SERVER['SCRIPT_FILENAME'], '.php') . "<br><br>";
?>
<script>
Call_Count = 1;
function Test(Option, El, Call_Count){ //____________________________
//El.disabled = true;
//if (Option === "Overwrite_File"){document.getElementById("Response_Overwrite").innerHTML += "(Please Wait <?php echo $Overwrite_Sleep ?> Seconds) ";
//}else if (Option === "flock_Get_File_Content"){document.getElementById("Response_flock_Get_Content").innerHTML += 'File Content is: ';
//}else{document.getElementById("Response_Get_Content").innerHTML += 'File Content is: '}
var http = new XMLHttpRequest();
http.open('POST', ""); //blank url (send to same page)
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); //necessary to send "Request" POST key below to php
http.onreadystatechange = function(){
if (this.readyState === 4) { //"4", request finished and response is ready!
if (Option === "Overwrite_File"){document.getElementById("Response_Overwrite").innerHTML += this.responseText + " (Call " + Call_Count + ")<br>";
}else if (Option === "flock_Get_File_Content"){
document.getElementById("Response_flock_Get_Content").innerHTML += '"' + this.responseText + '" (Call ' + Call_Count + ')<br>';
}else{document.getElementById("Response_Get_Content").innerHTML += '"' + this.responseText + '" (Call ' + Call_Count + ')<br>';}
El.disabled = false;
}
};
http.send('Request=' + Option);
}
</script>