Güncelleme
Sorunu çözdüm ve bir cevap gönderdim. Ancak benim çözümüm% 100 ideal değil. Ben daha çok sadece çıkarıyoruz symlink
gelen cache
ile clearstatcache(true, $target)
ya clearstatcache(true, $link)
ama bu işi yapmaz.
Ayrıca, ilk olarak semboliklerin önbelleğe alınmasını önlerim veya oluşturduktan hemen sonra symlink'i önbellekten kaldırırım. Ne yazık ki, hiç şansım yoktu. Herhangi bir nedenle clearstatcache(true)
bir symlink oluşturduktan sonra çalışmıyor, yine de önbelleğe alınır.
Cevabımı geliştirebilecek ve bu sorunları çözebilecek olan herkese ödül vereceğim .
Düzenle
Ben clearstatcache
sadece her symlink için önbelleği temizlemek gerekir, böylece her zaman çalıştırılır bir dosya oluşturarak kodumu optimize etmeye çalıştım . Bazı nedenlerden dolayı, bu işe yaramaz. clearstatcache
a her symlink
yola dahil edildiğinde çağrılmalı ama neden? Sahip olduğum çözümü optimize etmenin bir yolu olmalı.
Ben kullanıyorum PHP 7.3.5
ile nginx/1.16.0
. Bazen file_get_contents
a kullanırken yanlış değeri döndürür symlink
. Sorun, bir symlink'i sildikten ve yeniden oluşturduktan sonra eski değeri önbellekte kalır. Bazen doğru değer, bazen de eski değer döndürülür. Rastgele görünüyor.
Önbelleği temizlemeye veya önbelleğe almayı engellemeye çalıştım:
function symlink1($target, $link)
{
realpath_cache_size(0);
symlink($target, $link);
//clearstatcache(true);
}
Önbelleğe almayı gerçekten devre dışı bırakmak istemiyorum ancak file_get_contents ile% 100 doğruluk oranına ihtiyacım var.
Düzenle
Çok uzun ve karmaşık olduğu için kaynak kodumu gönderemiyorum, bu yüzden sorunu yeniden yaratan minimal, tekrarlanabilir bir örnek (index.php) oluşturduk:
<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
Yapılandırma ile ilgili bir sorun olması muhtemel görünüyordu . Bu çizgilere sahip olmamak soruna neden olabilir:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
İşte benim Nginx
yapılandırma (yukarıdaki satırları dahil ettik görebilirsiniz):
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;
}
Şu anda yukarıdaki örnek https://www.websemantica.co.uk adresinde canlı var .
Forma birkaç değer eklemeyi deneyin. Success!
Her seferinde mavi renkte görüntülenmelidir . Bazen Failure!
kırmızı renkte gösterilir. Bu değiştirmek için epeyce Sayfa yenilemeleri sürebilir Success!
için Failure!
veya tersi. Sonunda, Success!
her seferinde gösterecektir , bu nedenle bir tür önbellek sorunu olmalıdır.
realpath
ile file_get_conents
ve hiç şans kullanmayı denedim . Hala bazen önbellekten yüklenir.
realpath
, aynı şeyclearstatcache(true); file_get_conents(realpath($fileName));
realpath
işlev sayfasında çok yararlı bir yorum buldum . Belki size yardımcı olabilir.