Cache images on php script

早过忘川 提交于 2020-01-03 05:12:10

问题


I am using this great randomizer code found here: http://alistapart.com/article/randomizer , but the images are not saved on the browser's cache which means they refresh whenever the site reloads.

Is it possible to keep the images cached on the following code? The reason I am using this script is that php parse on css doesn't work on my server for some reason.

<?php

$folder = '.';
$extList = array();
    $extList['gif'] = 'image/gif';
    $extList['jpg'] = 'image/jpeg';
    $extList['jpeg'] = 'image/jpeg';
    $extList['png'] = 'image/png';

$img = null;

if (substr($folder,-1) != '/') {
    $folder = $folder.'/';
}

if (isset($_GET['img'])) {
    $imageInfo = pathinfo($_GET['img']);
    if (
        isset( $extList[ strtolower( $imageInfo['extension'] ) ] ) &&
        file_exists( $folder.$imageInfo['basename'] )
    ) {
        $img = $folder.$imageInfo['basename'];
    }
} else {
    $fileList = array();
    $handle = opendir($folder);
    while ( false !== ( $file = readdir($handle) ) ) {
        $file_info = pathinfo($file);
        if (
            isset( $extList[ strtolower( $file_info['extension'] ) ] )
        ) {
            $fileList[] = $file;
        }
    }
    closedir($handle);

    if (count($fileList) > 0) {
        $imageNumber = time() % count($fileList);
        $img = $folder.$fileList[$imageNumber];
    }
}

if ($img!=null) {
    $imageInfo = pathinfo($img);
    $contentType = 'Content-type: '.$extList[ $imageInfo['extension'] ];
    header ($contentType);
    readfile($img);
} else {
    if ( function_exists('imagecreate') ) {
        header ("Content-type: image/png");
        $im = @imagecreate (100, 100)
            or die ("Cannot initialize new GD image stream");
        $background_color = imagecolorallocate ($im, 255, 255, 255);
        $text_color = imagecolorallocate ($im, 0,0,0);
        imagestring ($im, 2, 5, 5,  "IMAGE ERROR", $text_color);
        imagepng ($im);
        imagedestroy($im);
    }
}

?>

回答1:


Generating an E-tag and Cache-Control header will help you like this

<?php
  $folder   = '.';
  $extList  = array( "gif", "jpg", "jpeg", "png" );
  $image    = false;

  if ( substr( $folder, -1 ) != '/' ) {
    $folder = $folder.'/';
  }

  if ( isset( $_GET["img"] ) ) {
    $imageExtn  = strtolower( pathinfo( $_GET["img"], PATHINFO_EXTENSION ) );
    $imageName  = basename( $_GET["img"] );
    if ( in_array( $imageExtn, $extList ) && file_exists( $folder.$imageName ) ) {
      $image  = $folder.$imageName;
    }
  }
  else {
    $fileList = array();
    $handle   = opendir( $folder );
    while( false !== ( $file = readdir( $handle ) ) ) {
      $fileExtn = strtolower( pathinfo( $file, PATHINFO_EXTENSION ) );
      if ( in_array( $fileExtn, $extList ) ) {
        $fileList[] = $file;
      }
    }
    closedir( $handle );

    if ( !empty( $fileList ) ) {
      $imageNumber  = time() % count( $fileList );
      $image  = $folder.$fileList[$imageNumber];
    }
  }

  if ( $image !== false ) {
    $contents = implode( "", file( $image ) );
    $md5  = md5( $contents );
    $mtime  = filemtime( $image );
    $etag = etag( $md5, $mtime );

    $r_mtime  = 0;
    $r_etag   = null;

    if ( isset( $_SERVER["HTTP_IF_MODIFIED_SINCE"] ) ) {
      $r_mtime  = strtotime( $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
    }
    if ( isset( $_SERVER["HTTP_IF_NONE_MATCH"] ) ) {
      $r_etag   = trim( $_SERVER["HTTP_IF_NONE_MATCH"] );
    }

    if ( $mtime == $r_mtime && $r_etag == $etag ) {
      header( "HTTP/1.0 304 Not Modified", true, 304 );
      header( "HTTP/1.1 304 Not Modified", true, 304 );
      header( "Content-length: 0" );
      exit;
    }

    header( "Content-type: image/".strtolower( pathinfo( $image, PATHINFO_EXTENSION ) ) );
    header( "Last-Modified: ".gmdate( "D, d M Y H:i:s", $mtime )." GMT" );
    header( "ETag: ".$etag );
    header( "Expires: ".gmdate( "D, d M Y H:i:s", time()+3600 )." GMT" );
    header( "Cache-Control: max-age=3600" );
    header( "Cache-Control: public" );

    echo $contents;
    exit();
  }
  else {
    if ( function_exists( "imagecreate" ) ) {
      header( "Content-type: image/png" );
      $im = @imagecreate( 100, 100 ) or die( "Cannot initialize new GD image stream" );
      $background_color = imagecolorallocate( $im, 255, 255, 255 );
      $text_color = imagecolorallocate( $im, 0, 0, 0 );
      imagestring( $im, 2, 5, 5,  "IMAGE ERROR", $text_color );
      imagepng( $im );
      imagedestroy( $im );
    }
  }

  function etag( $string_1 = null, $string_2 = null, $quote = true ) {
    $quote  = ( $quote ) ? '"' : '';
    $etag   = sprintf( $quote."%s-%s".$quote, $string_1, $string_2 );
    return $etag;
  }
?>



回答2:


You can instruct a user's browser to cache your page for a really long time (up to a year, shown below), by specifying the cache duration in the header:

header('Cache-Control: max-age=31556926');

There are two caveats to this, however. First, browsers won't necessarily follow the caching instruction, and may choose to download a new copy of the image anyway. Second, this line must be placed somewhere on your page before any content.




回答3:


One solution is to use a cookie to store the image you've sent to the user, and always send that image:

if(!isset($_COOKIE['imgCookie']))
{
    //runs if the user doesn't have the cookie
    //run randomizer code
    //setcookie('imgCookie',$imageNumber);
} else {
    //runs if the user already has the cookie
    $imagenumber=$_COOKIE['imgCookie'];
}
//run code for sending image to user


来源:https://stackoverflow.com/questions/17297950/cache-images-on-php-script

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!