PHP "file_get_contents()" 函数可以在写入文件时读取文件吗?

Can PHP "file_get_contents()" function read a file while it's being written?

如果正在写入给定文件,PHP“file_get_contents()”函数如何处理请求?是等写完了再读文件,还是读文件失败?

“file_get_contents()”函数默认使用“flock()”函数吗?

文件一直在写入,return什么都没有,

import time

with open('output.file', 'wb') as file:
    for x in range(30):
        file.write(b'Test')

        time.sleep(1)
<?php
    var_dump(file_get_contents('output.file'));

输出string(0) ""(惠斯特开局)
输出string(120) "TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest"一次写入

我做了一些测试,确实,“file_get_contents()”没有使用“flock()”,也没有办法使用“LOCK_SH”标志作为替代!

如果正在写入文件,“file_get_contents()”不会在队列中等待,它会读取文件然后 returns 一个空字符串!

我写了“flock_file_get_contents()”函数作为替代,如果正在写入文件,它会在队列中等待,直到写入过程结束,然后再读取文件!

随时欢迎更好的解决方案!

[OBS]:

  • 我唯一不喜欢“flock()”的是它不按调用顺序处理请求!

[已编辑]:

<?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>