php动态生成图片实现浏览器缓存

2/22/2017来源:ASP.NET技巧人气:411

当我们用php实现网站图片尺寸重写时,默认情况下浏览器不会将重写的图片缓存本地,现在我告诉你们怎样让浏览器缓存这样的图片数据。 // 在php脚本文件加上以下代码

session_start(); header("Cache-Control: PRivate, max-age=10800, pre-check=10800"); header("Pragma: private"); header("Expires: " . date(DATE_RFC822,strtotime(" 2 day")));

1:如果浏览器已经有缓存版本,它会向后端传一个$_SERVER[‘HTTP_IF_MODIFIED_SINCE’] ,简单的做法我们只需要告诉浏览器用缓存即可。

if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])){ // if the browser has a cached version of this image, send 304 header('Last-Modified: '.$_SERVER['HTTP_IF_MODIFIED_SINCE'],true,304); exit; }

2:如果浏览器有缓存版本,更明智的做法是,后端判断图片有没有更新,对应告知浏览器是否用缓存版本

$img = "some_image.png"; if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && (strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == filemtime($img))) { // send the last mod time of the file back header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($img)).' GMT', true, 304); exit; }

完整的代码

session_start(); header("Cache-Control: private, max-age=10800, pre-check=10800"); header("Pragma: private"); header("Expires: " . date(DATE_RFC822,strtotime(" 2 day"))); $img = "some_image.png"; if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && (strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == filemtime($img))) { // send the last mod time of the file back header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($img)).' GMT', true, 304); exit; }

// 裁剪图片,并且告知浏览器缓存图片

$is = new ImageSizer($img); $is->resizeImage(75); // resize image to 75px wide // and here we send the image to the browser with all the stuff required for tell it to cache header("Content-type: image/jpeg"); header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($thumbnail)) . ' GMT'); $is->showImage();

图片裁剪类

class ImageSizer { var $_baseDir; var $_baseImg; var $_imgData; var $_newImg; var $_newData; var $_newFormat; var $_loadPath; var $_defaultColor = array(255,255,255); var $keepaspectRatio; var $makeBigger; function ImageSizer($baseDir) { $this->changeBaseDir($baseDir); $this->keepAspectRatio = true; $this->makeBigger = false; } function changeBaseDir($baseDir) { $this->_baseDir = $baseDir; } function setDefaultColor($r, $g, $b) { $this->_defaultColor = array($r, $g, $b); } function changeFormat($str) { $str = strtolower($str); if ($str == 'jpg') $str = "jpeg"; $acceptable_formats = array('jpeg', 'gif', 'png'); if (!in_array($str, $acceptable_formats)) return false; $this->_newFormat = $str; } function loadImage($imgPath) { // $this->_imgData = getimagesize($this->_baseDir. $imgPath); $this->_imgData = getimagesize( $imgPath); $this->_imgData['funcType'] = preg_replace('#image/#i', '', $this->_imgData['mime']); $acceptable_formats = array('jpeg', 'gif', 'png'); if (!in_array($this->_imgData['funcType'], $acceptable_formats)) return false; $this->_newData = $this->_imgData; $funcName = 'imagecreatefrom' . $this->_imgData['funcType']; //$this->_newImg = $this->_baseImg = $funcName($this->_baseDir. $imgPath); $this->_newImg = $this->_baseImg = @$funcName( $imgPath); if(!$this->_baseImg){ echo " Failed on this image $imgPath "; return false; } $this->_loadPath = $imgPath; return true; } /*function genImageData(){ $funcName = 'image'.$this->getNewType(); $data = $funcName($this->_newImg ? $this->_newImg : $this->_baseImg); return $data; }*/ function resizeImage($w, $h, $crop=false) { $current_w = $this->getWidth(); $current_h = $this->getHeight(); $src_x = $src_y = 0; $dst_x = $dst_y = 0; if($w && $h && $crop=="f"){ // fill in the image centre it in white. // all the src stuff stays the same, just changing the destination suff $src_x = 0; $src_y = 0; $current_h = $current_h; $current_w = $current_w; // the destination stuff changes if($h && $w){ $h_percent = $percent = $h / $current_h; $w_percent = $percent = $w / $current_w; $percent = min($h_percent, $w_percent); }else if($h){ $h_percent = $percent = $h / $current_h; $percent = $h_percent; }else if($w){ $w_percent = $percent = $w / $current_w; $percent = $w_percent; } $dst_w = $current_w * $percent; $dst_h = $current_h * $percent; $new_w = $w; $new_h = $h; // work out destination x and y points $dst_x = ($new_w - $dst_w)/2; $dst_y = ($new_h - $dst_h)/2; }else if($w && $h && $crop=="c"){ $dst_w = $w; $dst_h = $h; $new_w = $w; $new_h = $h; // if the image we are tyring to crop is smaller than the crop request we dont do aynthing if($w > $current_w || $h > $current_h){ // the image is smaller than we are trying to crop! }else{ //the image is bigger on x and y axis. // check if we can fit horizontally $w_percent = $current_w/$w; $h_percent = $current_h/$h; if($w_percent < $h_percent){ $src_x = 0; $src_y = ($current_h/2) - (($h * $w_percent)/2); $current_w = $current_w; $current_h = ($h * $w_percent); }else{ $src_x = ($current_w/2) - (($w * $h_percent)/2); $src_y = 0; $current_w = ($w * $h_percent); $current_h = $current_h; } } }else if ($this->keepAspectRatio) { $percent = 1; // if ($current_w > $w || $current_h > $h || $this->makeBigger) { $do_resize=false; if($w && $current_w > $w){ $do_resize=true; }else if($h && $current_h > $h){ $do_resize=true; }else if($w && $current_w < $w && $this->makeBigger){ $do_resize=true; }else{ // imaeg is alreaedy smaller than requested size } if ( $do_resize ) { if($h && $w){ $h_percent = $percent = $h / $current_h; $w_percent = $percent = $w / $current_w; $percent = min($h_percent, $w_percent); }else if($h){ $h_percent = $percent = $h / $current_h; $percent = $h_percent; }else if($w){ $w_percent = $percent = $w / $current_w; $percent = $w_percent; } } $dst_w = $new_w = $current_w * $percent; $dst_h = $new_h = $current_h * $percent; } else{ $dst_w = $new_w = $w; $dst_h = $new_h = $h; } $this->_newImg = ImageCreateTrueColor($new_w, $new_h); $this->_newData = array($new_w, $new_h); if ($this->getNewType() == 'png' || $this->getNewType() == 'gif') { // This preserves the transparency imageAlphaBlending($this->_newImg, false); imageSaveAlpha($this->_newImg, true); } else { // This is if converting from PNG to another image format list($r, $g, $b) = $this->_defaultColor; $color = imagecolorallocate($this->_newImg, $r, $g, $b); imagefilledrectangle($this->_newImg, 0,0, $new_w, $new_h, $color); } // dst_w dst_h src_w src_h imagecopyresampled($this->_newImg, $this->_baseImg, $dst_x, $dst_y,$src_x,$src_y, $dst_w, $dst_h, $current_w, $current_h); return true; } function showImage() { header('Content-type: ' . $this->getNewMime()); $funcName = 'image'.$this->getNewType(); $funcName($this->_newImg ? $this->_newImg : $this->_baseImg); } function saveToFile($fileloc) { $funcName = 'image'.$this->getNewType(); $funcName($this->_newImg ? $this->_newImg : $this->_baseImg, $fileloc,100); } function addWatermark($pngloc,$offset_x=0) { $overlay = imagecreatefrompng($pngloc); imageAlphaBlending($overlay, false); imageSaveAlpha($overlay, true); imagecopy($this->_newImg, $overlay, (imagesx($this->_newImg))-(imagesx($overlay)+$offset_x), (imagesy($this->_newImg))-(imagesy($overlay)), 0, 0, imagesx($overlay), imagesy($overlay)); } function getBaseDir() { return $this->_baseDir; } function getWidth() { return $this->_imgData[0]; } function getHeight() { return $this->_imgData[1]; } function getMime() { return $this->_imgData['mime']; } function getType() { return $this->_imgData['funcType'];} function getNewWidth() { return $this->_newData[0]; } function getNewHeight() { return $this->_newData[1]; } function getNewMime() {return $this->_newFormat ? 'image/' . $this->_newFormat : $this->_imgData['mime'];} function getNewType() {return $this->_newFormat ? $this->_newFormat : $this->_imgData['funcType'];} }