title: file_get_contents getting wrong results
body: <p><strong>Update</strong></p>
  
  <p>I solved the problem and posted an answer. However, my solution isn't 100% ideal. I would much rather only remove the <code>symlink</code> from the <code>cache</code> with <code>clearstatcache(true, $target)</code> or <code>clearstatcache(true, $link)</code> but that doesn't work.</p>
  
  <p>I would also much rather prevent the caching of symlinks in the first place or remove the symlink from the cache immediately after generating it. Unfortunately, I had no luck with that. For some reason <code>clearstatcache(true)</code> after creating a symlink does not work, it still gets cached.</p>
  
  <p>I will happily award the bounty to anyone that can improve my <a href="https://stackoverflow.com/questions/58712126/file-get-contents-getting-wrong-results/59072152#59072152">answer</a> and solve those issues.</p>
  
  <p><strong>Edit</strong></p>
  
  <p>I've attempted to optimize my code by generating a file everytime <code>clearstatcache</code> is run, so that I only need to clear the cache once for each symlink. For some reason, this does not work. <code>clearstatcache</code> needs to be called every time a <code>symlink</code> is including in the path, but why? There must be a way to optimize the solution I have.</p>
  
  <hr>
  
  <p>I am using <code>PHP 7.3.5</code> with <code>nginx/1.16.0</code>. Sometimes <code>file_get_contents</code> returns the wrong value when using a <code>symlink</code>. The problem is after deleting and recreating a symlink, its old value remains in the cache. Sometimes the correct value is returned, sometimes the old value. It appears random.</p>
  
  <p>I've tried to clear the cache or prevent caching with:</p>
  
  <pre><code>function symlink1($target, $link)
  {
      realpath_cache_size(0);
      symlink($target, $link);
      //clearstatcache(true);
  }
  </code></pre>
  
  <p>I don't really want to disable caching but I still need 100% accuracy with file_get_contents.</p>
  
  <p><strong>Edit</strong></p>
  
  <p>I am unable to post my source code, as it is way too long and complex, so I have created a minimal, reproducible example (index.php) that recreates the problem:</p>
  
  <pre><code>&lt;h1&gt;Symlink Problem&lt;/h1&gt;
  &lt;?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']) &amp;&amp; !empty($_POST['id']) &amp;&amp; ctype_digit($_POST['insert-after']) &amp;&amp; ctype_alnum($_POST['id']))
      {
          $nos = array_values(array_diff(scandir($dir.'/nos'), array('..', '.')));
          $total = count($nos);
          if ($total &lt;= 100)
          {
              for ($i = $total; $i &gt;= $_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 '&lt;br&gt;';
              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 '&lt;h2&gt;Ids from nos directory&lt;/h2&gt;';
      foreach ($nos as $no)
      {
          echo ($no + 1).':'.file_get_contents("$dir/nos/$no/id.txt").'&lt;br&gt;';
      }
      echo '&lt;h2&gt;Ids from using symlinks&lt;/h2&gt;';
      $ids = array_values(array_diff(scandir($dir.'/ids'), array('..', '.')));
      if (count($ids) &gt; 0)
      {
          $success = true;
          foreach ($ids as $id)
          {
              $id1 = file_get_contents("$dir/ids/$id/id.txt");
              echo $id.':'.$id1.'&lt;br&gt;';
              if ($id !== $id1)
                  $success = false;
          }
          if ($success)
              echo '&lt;b&gt;&lt;font color="blue"&gt;Success!&lt;/font&gt;&lt;/b&gt;&lt;br&gt;';
          else
              echo '&lt;b&gt;&lt;font color="red"&gt;Failure!&lt;/font&gt;&lt;/b&gt;&lt;br&gt;';
      }
  ?&gt;
  &lt;br&gt;
  &lt;h2&gt;Insert ID after&lt;/h2&gt;
  &lt;form method="post" action="/"&gt;
      &lt;select name="insert-after"&gt;
          &lt;?php
              for ($i = 0; $i &lt; $total; $i++)
                  echo '&lt;option value="'.$i.'"&gt;'.$i.'&lt;/option&gt;';
          ?&gt;
      &lt;/select&gt;
      &lt;input type="text" placeholder="ID" name="id"&gt;&lt;br&gt;
      &lt;input type="submit" name="submit" value="Insert"&gt;&lt;br&gt;
  &lt;/form&gt;
  &lt;h2&gt;Clear all&lt;/h2&gt;
  &lt;form method="post" action="/"&gt;
      &lt;input type="submit" name="clear-all" value="Clear All"&gt;&lt;br&gt;
  &lt;/form&gt;
  &lt;script&gt;
      if (window.history.replaceState)
      {
          window.history.replaceState( null, null, window.location.href );
      }
  &lt;/script&gt;
  </code></pre>
  
  <p>It seemed very likely to be a problem with <code>Nginx</code> configuration. Not having these lines can cause the problem:</p>
  
  <pre><code>fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
  fastcgi_param DOCUMENT_ROOT $realpath_root;
  </code></pre>
  
  <p>Here is my <code>Nginx</code> configuration (you can see I have included the above lines):</p>
  
  <pre><code>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;
  }
  </code></pre>
  
  <p>Currently I have the above example live at <a href="https://www.websemantica.co.uk" rel="nofollow noreferrer">https://www.websemantica.co.uk</a>.</p>
  
  <p>Try adding a few values in the form. It should display <code>Success!</code> in blue every time. Sometimes is shows <code>Failure!</code> in red. It may take quite a few page refreshes to change from <code>Success!</code> to <code>Failure!</code> or vice-versa. Eventually, it will show <code>Success!</code> every time, therefore there must be some sort of caching problem.</p>