0

I am using a PHP script to display images stored as blobs in my database.

I used to display them with the following script.

<?php

if(!empty($_GET['user_id'])){//script to display an image from the database you basically just get the id from the picture in matter and fucking access it
include_once "DBH.php";
//Get image data from database

$id = mysqli_real_escape_string($conn, $_GET['user_id']);
$result = $conn->query("SELECT image FROM profilePictures WHERE user_id = $id");
if($result->num_rows > 0){
    $imgData = $result->fetch_assoc();
    header("Content-type: image"); 
    echo $imgData['image']; 
}else{
    echo 'Image not found...';
}
}
?>

In the context where

<img src = 'displayProfilePicture.php?user_id=n'>

The div containing the divs are updated frequently and to update the users image seems like a lot of unnecessary processing. I want to cache the profilepictures in the webpage so that I don't have to query them from the database every time. I started reading a lot about how you could cache the images but could not find any content on how to display the cached images.

This is a problem for me as the images flicker for a bit every time the img is updated with the PHP script. In an optimal world I see that the img load one time and then after that it does not have to load.

The context which I use the display img script is in a chat that is updated with a timer-interval within an ajax-request

 $("#chatlogs").load("logs.php");
 

logs.php

 if(isset($_SESSION['chatRoomId'])){
 while ($extract = mysqli_fetch_array($result1))
 {
   $from = $extract['from'];

   //make an object to echo.
   if($from == $id){
   echo "<div class='chatContainer self'>
    <div class = 'imgContainer'>
     <img src='displayProfilePicture.php?user_id=$selfId'>
    </div>
   <div class='content'>
    <div class = 'message'>
        ". $extract['msg'] ."
    </div>
</div>
</div>";
}else{
echo "<div class='chatContainer friend'>
<div class = 'imgContainer'>
  <img src='displayProfilePicture.php?user_id=$guestId'>
</div>
<div class='content'>
    <div class = 'message'>
        ". $extract['msg'] ."
    </div>
</div>
</div>";
}
}
}
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Albin wärme
  • 251
  • 1
  • 14
  • You must set the caching headers, before sending the image. – Kerkouch Mar 10 '18 at 19:21
  • Also, I noticed that when the image was not found why you didn't send a 404 Not Found header, so the browser will understand that the resource was not found. – Kerkouch Mar 10 '18 at 19:22
  • Also `mysqli_real_escape_string` is not going to protect you from a sql injection here!! – Kerkouch Mar 10 '18 at 19:25

1 Answers1

1

I think this is what you looking for:

<?php

if(empty($_GET['user_id']) || !preg_match( '/^[0-9]+$/' , $_GET['user_id'])){
    header( '400 Bad Request' );
    exit(1);
}

include_once "DBH.php";


$user_id = intval( $_GET['user_id'] );

$result = $conn->query("SELECT image FROM profilePictures WHERE user_id = $user_id");
if($result->num_rows == 0){
    // Not Found
    header('404 Not Found');
    exit(1);
}

$imgData = $result->fetch_assoc();
header("Content-type: image"); 
$cache_for = 3600; // One hour in seconds 
$cache_until = gmdate("D, d M Y H:i:s", time() + $cache_for) . " GMT";
header("Expires: $cache_until");
header("Pragma: cache");
header("Cache-Control: max-age=$cache_for");
echo $imgData['image'];
exit(0);

Comments

First I checked if the user_id is supplied in the request, if so then check if it was a valid number if it doesn't then respond with a 400 error.

And also I have removed a SQLi in your code src='displayProfilePicture.php?user_id=-1 or 1=1.

And I have set the caching headers, so the browser will cache the image for an hour.

Kerkouch
  • 1,446
  • 10
  • 14
  • When we set the cache... if you dont mind me asking. How is it then being stored? Because i see this code working in my project but to me it seems as if the query is still being processed every call of the script. Is it just that the img is stored in the header so that it can get the img faster? Caching for me is very abstract. So to get some clearance on the subject would be very nice. I tried looking it up but nobody has a concret example as this. Best regards – Albin wärme Mar 11 '18 at 10:31
  • I just found this question https://stackoverflow.com/questions/7324242/headers-for-png-image-output-to-make-sure-it-gets-cached-at-browser – Kerkouch Mar 11 '18 at 23:37