Aggiornare
Ho risolto il problema e pubblicato una risposta. Tuttavia, la mia soluzione non è l'ideale al 100%. Preferirei di gran lunga rimuovere solo symlink
il cache
con clearstatcache(true, $target)
o clearstatcache(true, $link)
ma non funziona.
Preferirei molto di più impedire la memorizzazione nella cache dei collegamenti simbolici in primo luogo o rimuovere il collegamento simbolico dalla cache immediatamente dopo averlo generato. Sfortunatamente, non ho avuto fortuna con quello. Per qualche motivo, clearstatcache(true)
dopo aver creato un collegamento simbolico non funziona, viene comunque memorizzato nella cache.
Felicemente assegnerò la generosità a chiunque possa migliorare la mia risposta e risolvere quei problemi.
modificare
Ho tentato di ottimizzare il mio codice generando un file ogni volta che clearstatcache
viene eseguito, quindi ho solo bisogno di cancellare la cache una volta per ogni collegamento simbolico. Per qualche motivo, questo non funziona. clearstatcache
deve essere chiamato ogni volta che un symlink
è incluso nel percorso, ma perché? Ci deve essere un modo per ottimizzare la soluzione che ho.
Sto usando PHP 7.3.5
con nginx/1.16.0
. A volte file_get_contents
restituisce un valore errato quando si utilizza a symlink
. Il problema è dopo aver eliminato e ricreato un collegamento simbolico, il suo vecchio valore rimane nella cache. A volte viene restituito il valore corretto, a volte il valore precedente. Sembra casuale.
Ho provato a cancellare la cache o impedire la memorizzazione nella cache con:
function symlink1($target, $link)
{
realpath_cache_size(0);
symlink($target, $link);
//clearstatcache(true);
}
Non voglio davvero disabilitare la memorizzazione nella cache ma ho ancora bisogno del 100% di precisione con file_get_contents.
modificare
Non riesco a pubblicare il mio codice sorgente, poiché è troppo lungo e complesso, quindi ho creato un esempio minimale e riproducibile (index.php) che ricrea il problema:
<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>
Sembrava molto probabile che fosse un problema con la Nginx
configurazione. Non avere queste righe può causare il problema:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
Ecco la mia Nginx
configurazione (puoi vedere che ho incluso le righe sopra):
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;
}
Attualmente ho l'esempio sopra in diretta su https://www.websemantica.co.uk .
Prova ad aggiungere alcuni valori nel modulo. Dovrebbe apparire Success!
in blu ogni volta. A volte viene mostrato Failure!
in rosso. Si può prendere parecchi aggiornamenti di pagina per passare da Success!
a Failure!
o viceversa. Alla fine, verrà visualizzato Success!
ogni volta, quindi ci deve essere una sorta di problema di memorizzazione nella cache.
realpath
con file_get_conents
e senza fortuna. A volte si carica ancora dalla cache.
realpath
, ma qualcosa del genereclearstatcache(true); file_get_conents(realpath($fileName));
realpath
pagina delle funzioni . Forse potrebbe aiutarti.