Memperbarui
Saya memecahkan masalah dan mengirim jawaban. Namun, solusi saya tidak 100% ideal. Saya lebih suka hanya menghapus symlink
dari cache
dengan clearstatcache(true, $target)
atau clearstatcache(true, $link)
tetapi itu tidak berhasil.
Saya juga lebih suka mencegah caching symlink di tempat pertama atau menghapus symlink dari cache segera setelah membuatnya. Sayangnya, saya tidak beruntung dengan itu. Untuk beberapa alasan clearstatcache(true)
setelah membuat symlink tidak berfungsi, itu masih di-cache.
Saya akan dengan senang hati memberikan hadiah kepada siapa pun yang dapat meningkatkan jawaban saya dan menyelesaikan masalah-masalah itu.
Edit
Saya telah berusaha untuk mengoptimalkan kode saya dengan menghasilkan file setiap kali clearstatcache
dijalankan, sehingga saya hanya perlu menghapus cache sekali untuk setiap symlink. Untuk beberapa alasan, ini tidak berhasil. clearstatcache
perlu dipanggil setiap kali a symlink
termasuk di jalan, tapi mengapa? Pasti ada cara untuk mengoptimalkan solusi yang saya miliki.
Saya menggunakan PHP 7.3.5
dengan nginx/1.16.0
. Terkadang file_get_contents
mengembalikan nilai yang salah saat menggunakan a symlink
. Masalahnya adalah setelah menghapus dan menciptakan kembali symlink, nilainya yang lama tetap ada di cache. Terkadang nilai yang benar dikembalikan, terkadang nilai lama. Tampaknya acak.
Saya sudah mencoba menghapus cache atau mencegah caching dengan:
function symlink1($target, $link)
{
realpath_cache_size(0);
symlink($target, $link);
//clearstatcache(true);
}
Saya tidak benar-benar ingin menonaktifkan caching tetapi saya masih membutuhkan akurasi 100% dengan file_get_contents.
Edit
Saya tidak dapat memposting kode sumber saya, karena terlalu panjang dan rumit, jadi saya telah membuat contoh minimal yang dapat direproduksi (index.php) yang menciptakan masalah:
<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>
Tampaknya sangat mungkin menjadi masalah dengan Nginx
konfigurasi. Tidak memiliki garis-garis ini dapat menyebabkan masalah:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
Ini adalah Nginx
konfigurasi saya (Anda dapat melihat saya telah menyertakan baris di atas):
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;
}
Saat ini saya memiliki contoh di atas secara langsung di https://www.websemantica.co.uk .
Coba tambahkan beberapa nilai dalam formulir. Itu harus ditampilkan Success!
dengan warna biru setiap kali. Terkadang ditampilkan Failure!
dalam warna merah. Mungkin diperlukan beberapa kali penyegaran halaman untuk berubah dari Success!
menjadi Failure!
atau sebaliknya. Akhirnya, itu akan ditampilkan Success!
setiap waktu, oleh karena itu harus ada semacam masalah caching.
realpath
dengan file_get_conents
dan tidak berhasil. Kadang-kadang masih memuat dari cache.
realpath
, tetapi sesuatu seperticlearstatcache(true); file_get_conents(realpath($fileName));
realpath
halaman fungsi . Mungkin itu bisa membantu Anda.