PHP image caching in server

Hello all,
I am working on a project that creates text to image using PHP. Is there any way to cache them in server sothat if the same querry is made, previously cached image will be displayed. ?
Where do caching normally occurs? Browser or web server?
Your simple help is much appreciated.
Thanks.

Welcome to SitePoint!

Sure, what I tend to do is keep a directory of the final images. Then use a rewrite rule which serves the image if present, otherwise pass off the creation to PHP.

This allows you to skip PHP altogether if the image exists.

Thank you for the kind reply.

I have a php file (text.php) that will create text to image.
ie domain.com/txt.php?text=hello will outputs an image with hello written on it.
I need that image to be cached as it is called very often.

Can some one please guide me, what all modifications needed to make caching occur in the below code…

This is the content of text.php file


<?php


$txt=$_GET["text"];
$im = imagecreatetruecolor(120, 20);
$text_color = imagecolorallocate($im, 255, 255, 255);



imagestring($im, 10, 1, 1,  $txt, $text_color);

header('Content-type: image/jpeg');


imagejpeg($im);


imagedestroy($im);
?>

**I already made such a post in another forum but unfortunately I couldn’t find an answer :frowning:

You can add a second parameter to imagejpeg to save the image to a file, like a folder named ‘cache’ for example.


<?php
define(
  'IMAGE_CACHE_DIR',
  dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cache'
);

if(false === is_dir(IMAGE_CACHE_DIR)){
  mkdir(IMAGE_CACHE_DIR);
}

function create_image($text){
  $im = imagecreatetruecolor(120, 20);
  $white = imagecolorallocate($im, 255, 255, 255);
  imagestring($im, 10, 1, 1, $text, $white);
  return imagejpeg($im, get_cache_filename($text));
}

function get_image($text){
  $cached_image = get_cache_filename($text);
  if(false === file_exists($cached_image)){
    create_image($text);
  }
  return file_get_contents($cached_image);
}

function get_cache_filename($text){
  return IMAGE_CACHE_DIR . DIRECTORY_SEPARATOR . sha1($text) . '.jpeg';
}

header('Content-type: image/jpeg');
echo get_image($_GET['text']);
exit;

*untested

oh my god!
it works… :slight_smile:
A million thanks AnthonySterling… you are awesome…

Mind if I add to that?


date_default_timezone_set('Europe/Amsterdam');

define(
	'IMAGE_CACHE_DIR',
	dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cache'
);

if (false === is_dir(IMAGE_CACHE_DIR)) {
	mkdir(IMAGE_CACHE_DIR);
}

function create_image($text) {
	$im = imagecreatetruecolor(120, 20);
	$white = imagecolorallocate($im, 255, 255, 255);
	imagestring($im, 10, 1, 1, $text, $white);
	return imagejpeg($im, get_cache_filename($text));
}

function get_image($text) {
	$image = get_cache_filename($text);
	if (false === file_exists($image)) {
		$image = create_image($text);
	} else {
		$lastModified = filemtime($image);
		header('last-modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . " GMT");
		if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && isset($_SERVER['SERVER_PROTOCOL'])) {
			$requested_time = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
			if ($requested_time == $lastModified) {
				header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified', false);
				exit;
			}
		}
	}
	return file_get_contents($image);
}

function get_cache_filename($text) {
	return IMAGE_CACHE_DIR . DIRECTORY_SEPARATOR . sha1($text) . '.jpeg';
}

header('Content-type: image/jpeg');
echo get_image($_GET['text']);
exit;

There was a minor bug in the get_image function; it didn’t return the correct value in case an image didn’t yet exist.

In addition, the script above sends the HTTP 304 Not Modified header to the browser in case the browser already has the image in cache, by comparing the last modification date of the image to the HTTP_IF_MODIFIED_SINCE request header, so you don’t have to send it again. Leverages the browser and the server :slight_smile:

The call to date_default_timezone_set is to avoid a warning from strtotime. If you already have a timezone defined somewhere else you can remove that. Or, change it to the appropriate timezone (>> list of available time zones in PHP) if you’re not in the Europe/Amsterdam timezone.

imagejpeg returns a boolean, you’re assuming it returns a filename?

Yikes! :blush:


$image = create_image($text);

should be


create_image($text);
return $image;