0

how could I clear the cache for the image instantly with my uploader? I'm currently trying this but isn't working. any suggestion? thank you !
ps : settings.php is the current page, and I'm using only one header location


the image is currently uploader some time, but not always, some time it doesn't work without a ctrl + maj + r

enter image description here

uploader code :

       <?php 

        // UPLOAD FICHIER

        if (isset($_POST['valider']))
        {
          if (isset($_FILES['avatar']) AND !empty($_FILES['avatar']['name']))
          { 
              $tailleMax = 1000000;
              $extensionsValide = array('jpg', 'png');

              if ($_FILES['avatar']['size'] < $tailleMax)
              {
                  $extensionsUpload = strtolower(substr(strrchr($_FILES['avatar']['name'], '.'), 1));

                  if (in_array($extensionsUpload, $extensionsValide))
                  {
                    $chemin = "../images/avatar/" . $_SESSION['id'] . "." . $extensionsUpload;
                    $resultat = move_uploaded_file($_FILES['avatar']['tmp_name'], $chemin);

                    $touxiang = $_SESSION['id'] . "." . $extensionsUpload;
                    $session = $_SESSION['id'];

                    if ($resultat)
                    {
                      $updateAvatar=$dbh->prepare("UPDATE members SET avatar = :avatar WHERE id = :id");
                      $updateAvatar->bindValue('avatar', $touxiang);
                      $updateAvatar->bindValue('id', $session);
                      $updateAvatar->execute();
                      

                      header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
                      header('Cache-Control: no-store, no-cache, must-revalidate');
                      header('Cache-Control: post-check=0, pre-check=0', FALSE);
                      header('Pragma: no-cache');                          
                      header('Location: settings');
                    }

                    else
                    {
                      echo "<p class='review_wrong'>error.</p>";
                    }

                  }

                  else
                  {
                    echo "<p class='review_wrong'>wrong format. jpeg png.</p>";                        
                  }

              }

              else
              {
                  echo "<p class='review_wrong'>File too large.</p>";
              }

          } // ISSET

        }

        ?>

        <div id="avatar_send_div">
          <input id="upload_header" type="file" name="avatar">
          <label for="upload_header" class="btn">Upload</label>

          <input id="submit_header" type="submit" name="valider" value="Validate">
        </div> 

show image :

        <?php 

        if (isset($_SESSION['id']) AND !empty($_SESSION['id']))
        {
          $id = $_SESSION['id'];

          $req = $dbh->prepare('SELECT * FROM members WHERE id = :id');
          $req->bindValue('id', $id);
          $req->execute();
          $userinfo = $req->fetch();              
        }

        ?>

        <div id="settings_div_img">
            <img id="settings_img" src="../images/avatar/<?php echo $userinfo['avatar'];?>">
        </div>

db :

enter image description here

  • How does the PHP code, that shows the avatar, look like ? – Luuk May 02 '22 at 17:42
  • I just have add it – UnSeulChemin May 02 '22 at 17:46
  • Why is the headers with `Cache-Control` and `Expires` not in show_image.php ? – Luuk May 02 '22 at 17:48
  • 1
    You cannot clear the cache from PHP's side as the cache prevents client requests from ever reaching the server in the first place. You need to ensure that the content is initially served with a suitably short cache expiry value. However, for infrequently-changing static data such as images a change in the content of the file should _also change the name of the file_. You're already storing the filename in the DB, just generate a more unique filename when a new file is uploaded. – Sammitch May 02 '22 at 17:51
  • this is the same page, show image is just the code above it – UnSeulChemin May 02 '22 at 17:52
  • how may I do that? every member have their own image with an id increment, this is the image name – UnSeulChemin May 02 '22 at 17:54
  • I added my table screenshot – UnSeulChemin May 02 '22 at 17:56
  • The easiest would be to just tack on a timestamp. So long as a user isn't uploading more than one avatar per second. :P – Sammitch May 02 '22 at 17:56
  • eg: `$chemin = "../images/avatar/" . $_SESSION['id'] . "-" . time() . "." . $extensionsUpload;` – Sammitch May 02 '22 at 17:58
  • In this case you'll also need to think about cleaning up old avatars, since you won't be overwriting those files anymore. – Sammitch May 02 '22 at 18:00
  • 2
    To note the obvious, the cache headers you send _impact the HTML document you are serving_. **Not** the images, the stylesheets, or anything else linked from your page. For more ideas, see [Refresh image with a new one at the same url](https://stackoverflow.com/questions/1077041/refresh-image-with-a-new-one-at-the-same-url/22429796). – Markus AO May 02 '22 at 18:21
  • not sure how I can do that but I will give a look thanks – UnSeulChemin May 02 '22 at 18:32

1 Answers1

0

As others have stated in the comments, you can't really clear the cache with PHP, certainly not the cached assets (images, CSS files, etc). Assets are almost all the time served directly by the webserver.

The HTTP headers that you are setting with PHP will only affect the document being returned by your PHP script, which in your case is an HTML page. Also, sending headers does not guarantee that the cached document will be cleared (it's the job of the user's browser to do that).

So you are generating an HTML page with URLs pointing to images served by the webserver. To control the cache of these images, you mostly want to configure the webserver itself (Apache, NGINX, etc)

That again won't necessarily work if the user already has a previously cached image.

A common technique to go around that and avoid having to generate new image filenames is to append a version id to the image URL and change it as new versions of the image are uploaded.

So instead of having example.net/john.png you would generate example.net/john.png?v=1 and then when you upload a new image, you generate a new URL example.net/john.png?v=2. You can basically append anything to the query string, the goal is to generate a new URL that the browser hasn't seen before.

You will find more techniques here: Refresh image with a new one at the same url

I hope that helps.

lbrandao
  • 3,706
  • 4
  • 32
  • 43