file_get_contents 得到错误的结果
file_get_contents getting wrong results
更新
我解决了问题并 post 给出了答案。但是,我的解决方案并非 100% 理想。我宁愿只用 clearstatcache(true, $target)
或 clearstatcache(true, $link)
从 cache
中删除 symlink
但这不起作用。
我也宁愿首先阻止符号链接的缓存,或者在生成符号链接后立即从缓存中删除它。不幸的是,我没有运气。由于某些原因 clearstatcache(true)
创建符号链接后不起作用,它仍然被缓存。
我很乐意将赏金奖励给任何可以改进我的 并解决这些问题的人。
编辑
我试图通过每次 clearstatcache
为 运行 时生成一个文件来优化我的代码,这样我只需要为每个符号链接清除缓存一次。出于某种原因,这不起作用。每次路径中包含 symlink
时都需要调用 clearstatcache
,但为什么呢?必须有一种方法可以优化我的解决方案。
我正在使用 PHP 7.3.5
和 nginx/1.16.0
。有时 file_get_contents
returns 使用 symlink
时的值错误。问题是删除并重新创建符号链接后,其旧值仍保留在缓存中。有时会返回正确的值,有时会返回旧值。它看起来是随机的。
我尝试清除缓存或阻止缓存:
function symlink1($target, $link)
{
realpath_cache_size(0);
symlink($target, $link);
//clearstatcache(true);
}
我真的不想禁用缓存,但我仍然需要 100% 的准确率 file_get_contents。
编辑
我无法 post 我的源代码,因为它太长太复杂,所以我创建了一个最小的、可重现的示例 (index.php) 来重现问题:
<h1>Symlink Problem</h1>
<?php
$dir = getcwd();
if (isset($_POST['clear-all']))
{
$nos = array_values(array_diff(scandir($dir.'/nos'), array('..', '.')));
foreach ($nos as $no)
{
unlink($dir.'/nos/'.$no.'/id.txt');
rmdir($dir.'/nos/'.$no);
}
foreach (array_values(array_diff(scandir($dir.'/ids'), array('..', '.'))) as $id)
unlink($dir.'/ids/'.$id);
}
if (!is_dir($dir.'/nos'))
mkdir($dir.'/nos');
if (!is_dir($dir.'/ids'))
mkdir($dir.'/ids');
if (isset($_POST['submit']) && !empty($_POST['id']) && ctype_digit($_POST['insert-after']) && ctype_alnum($_POST['id']))
{
$nos = array_values(array_diff(scandir($dir.'/nos'), array('..', '.')));
$total = count($nos);
if ($total <= 100)
{
for ($i = $total; $i >= $_POST['insert-after']; $i--)
{
$id = file_get_contents($dir.'/nos/'.$i.'/id.txt');
unlink($dir.'/ids/'.$id);
symlink($dir.'/nos/'.($i + 1), $dir.'/ids/'.$id);
rename($dir.'/nos/'.$i, $dir.'/nos/'.($i + 1));
}
echo '<br>';
mkdir($dir.'/nos/'.$_POST['insert-after']);
file_put_contents($dir.'/nos/'.$_POST['insert-after'].'/id.txt', $_POST['id']);
symlink($dir.'/nos/'.$_POST['insert-after'], $dir.'/ids/'.$_POST['id']);
}
}
$nos = array_values(array_diff(scandir($dir.'/nos'), array('..', '.')));
$total = count($nos) + 1;
echo '<h2>Ids from nos directory</h2>';
foreach ($nos as $no)
{
echo ($no + 1).':'.file_get_contents("$dir/nos/$no/id.txt").'<br>';
}
echo '<h2>Ids from using symlinks</h2>';
$ids = array_values(array_diff(scandir($dir.'/ids'), array('..', '.')));
if (count($ids) > 0)
{
$success = true;
foreach ($ids as $id)
{
$id1 = file_get_contents("$dir/ids/$id/id.txt");
echo $id.':'.$id1.'<br>';
if ($id !== $id1)
$success = false;
}
if ($success)
echo '<b><font color="blue">Success!</font></b><br>';
else
echo '<b><font color="red">Failure!</font></b><br>';
}
?>
<br>
<h2>Insert ID after</h2>
<form method="post" action="/">
<select name="insert-after">
<?php
for ($i = 0; $i < $total; $i++)
echo '<option value="'.$i.'">'.$i.'</option>';
?>
</select>
<input type="text" placeholder="ID" name="id"><br>
<input type="submit" name="submit" value="Insert"><br>
</form>
<h2>Clear all</h2>
<form method="post" action="/">
<input type="submit" name="clear-all" value="Clear All"><br>
</form>
<script>
if (window.history.replaceState)
{
window.history.replaceState( null, null, window.location.href );
}
</script>
看来很有可能是Nginx
配置的问题。没有这些行可能会导致问题:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
这是我的 Nginx
配置(你可以看到我已经包含了以上几行):
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.websemantica.co.uk;
root "/path/to/site/root";
index index.php;
location / {
try_files $uri $uri/ $uri.php$is_args$query_string;
}
location ~* \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $realpath_root$fastcgi_path_info;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTPS $https;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
fastcgi_index index.php;
fastcgi_read_timeout 3000;
}
if ($request_uri ~ (?i)^/([^?]*)\.php($|\?)) {
return 301 /$is_args$args;
}
rewrite ^/index$ / permanent;
rewrite ^/(.*)/$ / permanent;
}
目前我在 https://www.websemantica.co.uk.
有上面的例子
尝试在表单中添加一些值。它应该每次都以蓝色显示 Success!
。有时显示 Failure!
为红色。从 Success!
更改为 Failure!
可能需要多次页面刷新,反之亦然。最终,它每次都会显示 Success!
,因此肯定存在某种缓存问题。
有两个缓存。
首先是 OS 缓存,然后是 PHP 缓存。
在大多数情况下 clearstatcache(true)
在 file_get_contents(...)
完成工作之前。
但有时您还需要清除 OS 缓存。在 Linux 的情况下,我可以想到要清除的两个地方。 PageCache (1) 和 dentries/inodes (2).
这将同时清除:
shell_exec('echo 3 > /proc/sys/vm/drop_caches')
注意:这对于故障排除很有用,但不适合生产中的频繁调用,因为它会清除整个 OS 缓存并使系统花费几分钟的缓存时间-人口。
"The problem is after deleting and recreating a symlink"
如何删除符号链接?删除文件(或符号链接)应该会自动清除缓存。
否则,你会看到如果你这样做会发生什么:
// This has "race condition" written all around it
unlink($link);
touch($link);
unlink($link); // Remove the empty file
symlink($target, $link);
如果这不能解决问题,是否可能是 nginx 的问题,如 this issue?
尝试将所有操作记录到日志文件中,以查看实际上发生了什么。
或者也许...
...您可以完全不使用符号链接吗?例如,将 "filename" 和 "actual symlink target" 之间的映射存储在数据库、内存缓存、SQLite 文件,甚至 JSON 文件中。使用例如redis 或其他密钥库,您可以将 "filename" 与真正的符号链接目标相关联并完全绕过 OS 解析。
根据用例,这甚至可能比使用符号链接更快。
尝试将代码放在使用 Jquery 不断刷新的元素中,并强制重新验证和清除静态捕获。此代码已从@naveed 原始 answer.
修改而来
form.php:
<meta http-equiv="Cache-Control" content="no-store, must-revalidate" />
<meta http-equiv="Expires" content="0"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
jQuery(document).ready(function(){
jQuery('.ajaxform').submit( function() {
$.ajax({
url : $(this).attr('action'),
type : $(this).attr('method'),
dataType: 'json',
data : $(this).serialize(),
success : function( data ) {
// loop to set the result(value)
// in required div(key)
for(var id in data) {
jQuery('#' + id).html( data[id] );
}
}
});
return false;
});
});
var timer, delay = 30;
timer = setInterval(function(){
$.ajax({
type : 'POST',
url : 'profile.php',
dataType: 'json',
data : $('.ajaxform').serialize(),
success : function(data){
for(var id in data) {
jQuery('#' + id).html( data[id] );
}
}
}); }, delay);
</script>
<form action='profile.php' method='post' class='ajaxform'></form>
<div id='result'></div>
profile.php:
<?php
// All form data is in $_POST
// Now perform actions on form data here and create an result array something like this
clearstatcache();
$arr = array( 'result' => file_get_contents("./myfile.text") );
echo json_encode( $arr );
?>
太依赖OS水平了。那么尝试跳出框框怎么样。如何尝试通过 readlink
读取文件的真实位置,并使用该真实位置路径?
$realPath = shell_exec("readlink " . $yourSymlink);
$fileContent = file_get_contents($realPath);
这是 PHP 的预期行为,您可以看到 here because PHP uses realpath_cache
to stores the file paths due to performance enhancements 这样可以减少磁盘操作。
为了避免这种行为,也许您可以尝试在使用 get_file_contents
函数之前清除 realpath_cache
您可以尝试这样的操作:
clearstatcache();
$data = file_get_contents("Your File");
您可以在 PHP 文档上阅读有关 clearstatcache 的更多信息。
有两个问题导致了这个问题。
第一期
我已经发布并编辑了问题。是Nginx配置的问题
这些行:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $document_root;
需要替换为:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
第二期
第二个问题是我需要在调用 file_get_contents
之前调用 clearstatcache
。我只想在绝对必要的时候调用 clearstatcache
,所以我写了一个函数,只在目录包含 symlink
.
时才清除缓存
function file_get_contents1($dir)
{
$realPath = realpath($dir);
if ($realPath === false)
return '';
if ($dir !== $realPath)
{
clearstatcache(true);
}
return file_get_contents($dir);
}
我要留下我的第一个答案,因为它仍然是一个有效的答案。
我正在通过实施 clearstatcache(true,$filename).
改进@DanBray 的回答
There were two issues that caused the problem.
First issue
I already posted as and edit in the question. It's a problem with the
Nginx configuration.
These lines:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $document_root;
needed replaced with:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
Second issue
The second issue was I needed to call clearstatcache before calling
file_get_contents. I only want to call clearstatcache when it's
absolutely necessary, so I wrote a function that only clears the cache
when the directory includes a symlink.
function file_get_contents1234_hard_drives($dir_go_1){
$realPath = realpath($dir_go_1);
$myDirectory=opendir(dirname($realPath));
while($entryName=readdir($myDirectory)) {
$dirArray[]=$entryName;
}
/* Finds extensions of files used for my site theelectronichandbook.tech
function findexts ($filename) {
$filename=strtolower($filename);
$exts=split("[/\.]", $filename);
$n=count($exts)-1;
$exts=$exts[$n];
return $exts;
}*/
// Closes directory
closedir($myDirectory);
// Counts elements in array
$indexCount=count($dirArray);
for($ArPos=1;$ArPos<=$indexCount;$ArPos++){
/*used for my site theelectronichandbook.tech
if($_SERVER['QUERY_STRING']=="hidden"){
$H="";
$af="./";
$atext="Hide";
}else{
$H=".";
$af="./?hidden";
$at="Show";
}*/
if(strpos($dirArray[$ArPos], "Symlink") !== false){
clearstatcache(true,$dir_go_1);
}
}
return file_get_contents($dir_go_1);
}
我用我的网络服务器测试了上面的代码并且它有效。
更新
我解决了问题并 post 给出了答案。但是,我的解决方案并非 100% 理想。我宁愿只用 clearstatcache(true, $target)
或 clearstatcache(true, $link)
从 cache
中删除 symlink
但这不起作用。
我也宁愿首先阻止符号链接的缓存,或者在生成符号链接后立即从缓存中删除它。不幸的是,我没有运气。由于某些原因 clearstatcache(true)
创建符号链接后不起作用,它仍然被缓存。
我很乐意将赏金奖励给任何可以改进我的
编辑
我试图通过每次 clearstatcache
为 运行 时生成一个文件来优化我的代码,这样我只需要为每个符号链接清除缓存一次。出于某种原因,这不起作用。每次路径中包含 symlink
时都需要调用 clearstatcache
,但为什么呢?必须有一种方法可以优化我的解决方案。
我正在使用 PHP 7.3.5
和 nginx/1.16.0
。有时 file_get_contents
returns 使用 symlink
时的值错误。问题是删除并重新创建符号链接后,其旧值仍保留在缓存中。有时会返回正确的值,有时会返回旧值。它看起来是随机的。
我尝试清除缓存或阻止缓存:
function symlink1($target, $link)
{
realpath_cache_size(0);
symlink($target, $link);
//clearstatcache(true);
}
我真的不想禁用缓存,但我仍然需要 100% 的准确率 file_get_contents。
编辑
我无法 post 我的源代码,因为它太长太复杂,所以我创建了一个最小的、可重现的示例 (index.php) 来重现问题:
<h1>Symlink Problem</h1>
<?php
$dir = getcwd();
if (isset($_POST['clear-all']))
{
$nos = array_values(array_diff(scandir($dir.'/nos'), array('..', '.')));
foreach ($nos as $no)
{
unlink($dir.'/nos/'.$no.'/id.txt');
rmdir($dir.'/nos/'.$no);
}
foreach (array_values(array_diff(scandir($dir.'/ids'), array('..', '.'))) as $id)
unlink($dir.'/ids/'.$id);
}
if (!is_dir($dir.'/nos'))
mkdir($dir.'/nos');
if (!is_dir($dir.'/ids'))
mkdir($dir.'/ids');
if (isset($_POST['submit']) && !empty($_POST['id']) && ctype_digit($_POST['insert-after']) && ctype_alnum($_POST['id']))
{
$nos = array_values(array_diff(scandir($dir.'/nos'), array('..', '.')));
$total = count($nos);
if ($total <= 100)
{
for ($i = $total; $i >= $_POST['insert-after']; $i--)
{
$id = file_get_contents($dir.'/nos/'.$i.'/id.txt');
unlink($dir.'/ids/'.$id);
symlink($dir.'/nos/'.($i + 1), $dir.'/ids/'.$id);
rename($dir.'/nos/'.$i, $dir.'/nos/'.($i + 1));
}
echo '<br>';
mkdir($dir.'/nos/'.$_POST['insert-after']);
file_put_contents($dir.'/nos/'.$_POST['insert-after'].'/id.txt', $_POST['id']);
symlink($dir.'/nos/'.$_POST['insert-after'], $dir.'/ids/'.$_POST['id']);
}
}
$nos = array_values(array_diff(scandir($dir.'/nos'), array('..', '.')));
$total = count($nos) + 1;
echo '<h2>Ids from nos directory</h2>';
foreach ($nos as $no)
{
echo ($no + 1).':'.file_get_contents("$dir/nos/$no/id.txt").'<br>';
}
echo '<h2>Ids from using symlinks</h2>';
$ids = array_values(array_diff(scandir($dir.'/ids'), array('..', '.')));
if (count($ids) > 0)
{
$success = true;
foreach ($ids as $id)
{
$id1 = file_get_contents("$dir/ids/$id/id.txt");
echo $id.':'.$id1.'<br>';
if ($id !== $id1)
$success = false;
}
if ($success)
echo '<b><font color="blue">Success!</font></b><br>';
else
echo '<b><font color="red">Failure!</font></b><br>';
}
?>
<br>
<h2>Insert ID after</h2>
<form method="post" action="/">
<select name="insert-after">
<?php
for ($i = 0; $i < $total; $i++)
echo '<option value="'.$i.'">'.$i.'</option>';
?>
</select>
<input type="text" placeholder="ID" name="id"><br>
<input type="submit" name="submit" value="Insert"><br>
</form>
<h2>Clear all</h2>
<form method="post" action="/">
<input type="submit" name="clear-all" value="Clear All"><br>
</form>
<script>
if (window.history.replaceState)
{
window.history.replaceState( null, null, window.location.href );
}
</script>
看来很有可能是Nginx
配置的问题。没有这些行可能会导致问题:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
这是我的 Nginx
配置(你可以看到我已经包含了以上几行):
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.websemantica.co.uk;
root "/path/to/site/root";
index index.php;
location / {
try_files $uri $uri/ $uri.php$is_args$query_string;
}
location ~* \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $realpath_root$fastcgi_path_info;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTPS $https;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
fastcgi_index index.php;
fastcgi_read_timeout 3000;
}
if ($request_uri ~ (?i)^/([^?]*)\.php($|\?)) {
return 301 /$is_args$args;
}
rewrite ^/index$ / permanent;
rewrite ^/(.*)/$ / permanent;
}
目前我在 https://www.websemantica.co.uk.
有上面的例子尝试在表单中添加一些值。它应该每次都以蓝色显示 Success!
。有时显示 Failure!
为红色。从 Success!
更改为 Failure!
可能需要多次页面刷新,反之亦然。最终,它每次都会显示 Success!
,因此肯定存在某种缓存问题。
有两个缓存。
首先是 OS 缓存,然后是 PHP 缓存。
在大多数情况下 clearstatcache(true)
在 file_get_contents(...)
完成工作之前。
但有时您还需要清除 OS 缓存。在 Linux 的情况下,我可以想到要清除的两个地方。 PageCache (1) 和 dentries/inodes (2).
这将同时清除:
shell_exec('echo 3 > /proc/sys/vm/drop_caches')
注意:这对于故障排除很有用,但不适合生产中的频繁调用,因为它会清除整个 OS 缓存并使系统花费几分钟的缓存时间-人口。
"The problem is after deleting and recreating a symlink"
如何删除符号链接?删除文件(或符号链接)应该会自动清除缓存。
否则,你会看到如果你这样做会发生什么:
// This has "race condition" written all around it
unlink($link);
touch($link);
unlink($link); // Remove the empty file
symlink($target, $link);
如果这不能解决问题,是否可能是 nginx 的问题,如 this issue?
尝试将所有操作记录到日志文件中,以查看实际上发生了什么。
或者也许...
...您可以完全不使用符号链接吗?例如,将 "filename" 和 "actual symlink target" 之间的映射存储在数据库、内存缓存、SQLite 文件,甚至 JSON 文件中。使用例如redis 或其他密钥库,您可以将 "filename" 与真正的符号链接目标相关联并完全绕过 OS 解析。
根据用例,这甚至可能比使用符号链接更快。
尝试将代码放在使用 Jquery 不断刷新的元素中,并强制重新验证和清除静态捕获。此代码已从@naveed 原始 answer.
修改而来form.php:
<meta http-equiv="Cache-Control" content="no-store, must-revalidate" />
<meta http-equiv="Expires" content="0"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
jQuery(document).ready(function(){
jQuery('.ajaxform').submit( function() {
$.ajax({
url : $(this).attr('action'),
type : $(this).attr('method'),
dataType: 'json',
data : $(this).serialize(),
success : function( data ) {
// loop to set the result(value)
// in required div(key)
for(var id in data) {
jQuery('#' + id).html( data[id] );
}
}
});
return false;
});
});
var timer, delay = 30;
timer = setInterval(function(){
$.ajax({
type : 'POST',
url : 'profile.php',
dataType: 'json',
data : $('.ajaxform').serialize(),
success : function(data){
for(var id in data) {
jQuery('#' + id).html( data[id] );
}
}
}); }, delay);
</script>
<form action='profile.php' method='post' class='ajaxform'></form>
<div id='result'></div>
profile.php:
<?php
// All form data is in $_POST
// Now perform actions on form data here and create an result array something like this
clearstatcache();
$arr = array( 'result' => file_get_contents("./myfile.text") );
echo json_encode( $arr );
?>
太依赖OS水平了。那么尝试跳出框框怎么样。如何尝试通过 readlink
读取文件的真实位置,并使用该真实位置路径?
$realPath = shell_exec("readlink " . $yourSymlink);
$fileContent = file_get_contents($realPath);
这是 PHP 的预期行为,您可以看到 here because PHP uses realpath_cache
to stores the file paths due to performance enhancements 这样可以减少磁盘操作。
为了避免这种行为,也许您可以尝试在使用 get_file_contents
函数之前清除 realpath_cache
您可以尝试这样的操作:
clearstatcache();
$data = file_get_contents("Your File");
您可以在 PHP 文档上阅读有关 clearstatcache 的更多信息。
有两个问题导致了这个问题。
第一期
我已经发布并编辑了问题。是Nginx配置的问题
这些行:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $document_root;
需要替换为:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
第二期
第二个问题是我需要在调用 file_get_contents
之前调用 clearstatcache
。我只想在绝对必要的时候调用 clearstatcache
,所以我写了一个函数,只在目录包含 symlink
.
function file_get_contents1($dir)
{
$realPath = realpath($dir);
if ($realPath === false)
return '';
if ($dir !== $realPath)
{
clearstatcache(true);
}
return file_get_contents($dir);
}
我要留下我的第一个答案,因为它仍然是一个有效的答案。 我正在通过实施 clearstatcache(true,$filename).
改进@DanBray 的回答There were two issues that caused the problem.
First issue
I already posted as and edit in the question. It's a problem with the Nginx configuration.
These lines:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $document_root;
needed replaced with:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $realpath_root;
Second issue
The second issue was I needed to call clearstatcache before calling file_get_contents. I only want to call clearstatcache when it's absolutely necessary, so I wrote a function that only clears the cache when the directory includes a symlink.
function file_get_contents1234_hard_drives($dir_go_1){
$realPath = realpath($dir_go_1);
$myDirectory=opendir(dirname($realPath));
while($entryName=readdir($myDirectory)) {
$dirArray[]=$entryName;
}
/* Finds extensions of files used for my site theelectronichandbook.tech
function findexts ($filename) {
$filename=strtolower($filename);
$exts=split("[/\.]", $filename);
$n=count($exts)-1;
$exts=$exts[$n];
return $exts;
}*/
// Closes directory
closedir($myDirectory);
// Counts elements in array
$indexCount=count($dirArray);
for($ArPos=1;$ArPos<=$indexCount;$ArPos++){
/*used for my site theelectronichandbook.tech
if($_SERVER['QUERY_STRING']=="hidden"){
$H="";
$af="./";
$atext="Hide";
}else{
$H=".";
$af="./?hidden";
$at="Show";
}*/
if(strpos($dirArray[$ArPos], "Symlink") !== false){
clearstatcache(true,$dir_go_1);
}
}
return file_get_contents($dir_go_1);
}
我用我的网络服务器测试了上面的代码并且它有效。