Aktualisieren
Ich habe das Problem gelöst und eine Antwort gepostet. Meine Lösung ist jedoch nicht 100% ideal. Ich würde viel lieber nur symlink
das cache
mit clearstatcache(true, $target)
oder entfernen, clearstatcache(true, $link)
aber das funktioniert nicht.
Ich würde auch viel lieber das Zwischenspeichern von Symlinks verhindern oder den Symlink sofort nach dem Generieren aus dem Cache entfernen. Leider hatte ich damit kein Glück. Aus irgendeinem Grund clearstatcache(true)
funktioniert das Erstellen eines Symlinks nach dem Erstellen nicht.
Ich werde das Kopfgeld gerne an jeden vergeben, der meine Antwort verbessern und diese Probleme lösen kann.
Bearbeiten
Ich habe versucht, meinen Code zu optimieren clearstatcache
, indem ich bei jeder Ausführung eine Datei generiere , sodass ich den Cache für jeden Symlink nur einmal leeren muss. Aus irgendeinem Grund funktioniert dies nicht. clearstatcache
muss jedes Mal aufgerufen werden, wenn a symlink
in den Pfad aufgenommen wird, aber warum? Es muss eine Möglichkeit geben, meine Lösung zu optimieren.
Ich benutze PHP 7.3.5
mit nginx/1.16.0
. Gibt file_get_contents
bei Verwendung von a manchmal den falschen Wert zurück symlink
. Das Problem ist, dass nach dem Löschen und Neuerstellen eines Symlinks sein alter Wert im Cache verbleibt. Manchmal wird der richtige Wert zurückgegeben, manchmal der alte Wert. Es erscheint zufällig.
Ich habe versucht, den Cache zu leeren oder das Caching zu verhindern mit:
function symlink1($target, $link)
{
realpath_cache_size(0);
symlink($target, $link);
//clearstatcache(true);
}
Ich möchte das Caching nicht wirklich deaktivieren, benötige aber dennoch eine 100% ige Genauigkeit mit file_get_contents.
Bearbeiten
Ich kann meinen Quellcode nicht veröffentlichen, da er viel zu lang und komplex ist. Daher habe ich ein minimales, reproduzierbares Beispiel (index.php) erstellt, das das Problem neu erstellt:
<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>
Es schien sehr wahrscheinlich ein Problem mit der Nginx
Konfiguration zu sein. Das Fehlen dieser Leitungen kann das Problem verursachen:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
Hier ist meine Nginx
Konfiguration (Sie können sehen, dass ich die obigen Zeilen eingefügt habe):
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 /$1$is_args$args;
}
rewrite ^/index$ / permanent;
rewrite ^/(.*)/$ /$1 permanent;
}
Derzeit habe ich das obige Beispiel live unter https://www.websemantica.co.uk .
Versuchen Sie, dem Formular einige Werte hinzuzufügen. Es sollte Success!
jedes Mal blau angezeigt werden. Manchmal sind Shows Failure!
in rot. Es kann einige Seitenaktualisierungen dauern, um von Success!
zu Failure!
oder umgekehrt zu wechseln . Irgendwann wird es Success!
jedes Mal angezeigt, daher muss es eine Art Caching-Problem geben.
realpath
mit file_get_conents
und kein Glück. Es wird immer noch manchmal aus dem Cache geladen.
realpath
, sondern so etwas wieclearstatcache(true); file_get_conents(realpath($fileName));
realpath
Funktionsseite gefunden . Vielleicht könnte es dir helfen.