У меня есть PHP script, который вызывается с параметром ? img =.
Значение для этого параметра - URL (urlencoded) изображения.
Мой script проверяет, если это изображение уже сохранено на моем сервере.
Если нет - он загружает его. После этого он необязательно изменяет размер изображения и отправляет его в STDOUT, то есть обратно в запрашивающий браузер, с добавлением заголовков Content-Type и Last-modified:
Connection:close
Content-Type:image/jpeg
Date:Fri, 01 Jun 2012 08:28:30 GMT
Last-Modified:Fri, 01 Jun 2012 08:02:44 GMT
Server:Apache/2.2.15 (CentOS)
Transfer-Encoding:chunked
X-Powered-By:PHP/5.3.3
Это необходимо для решения некоторых проблем Flash/Crossdomain.xml и хорошо работает для меня с года:
Однако я хотел бы добавить функциональность для обработки входящего заголовка If-Modified-since, чтобы отправить ответ Not Modified 304.
Мои вопросы:
1) Возможно ли это даже в PHP, когда выполняется в Apache?
2) Как обрабатывать (то есть анализировать и производить) лучшие даты в PHP здесь?
Бонусный вопрос) Как добавить заголовок Content-Length для измененных изображений?
Мой код ниже (я пропустил часть загрузки CURL):
<?php
define('CACHE_DIR', '/var/www/cached_avatars/');
$img = urldecode($_GET['img']);
$cached = CACHE_DIR . md5($img);
# omitted downloading part for brevity
$readfh = fopen($cached, 'rb');
if ($readfh) {
flock($readfh, LOCK_SH);
$size = getimagesize($cached);
$w = $size[0];
$h = $size[1];
$type = $size[2];
$mime = $size['mime'];
# find the downscale factor to fit image into $maxw x $maxh
$scale = max($w / $maxw, $h / $maxh);
header('Content-Type: ' . $size['mime']);
header('Last-Modified: ' . gmdate('D, d M Y H:i:s T', filemtime($cached)));
$length = filesize($cached);
$buf = fread($readfh, $length);
fclose($readfh);
# the image is smaller than $maxw x $maxh, do not scale up
if ($scale <= 1) {
header('Content-Length: ' . $length);
print($buf);
return;
}
$tw = $w / $scale;
$th = $h / $scale;
$image = imagecreatefromstring($buf);
$thumb = imagecreatetruecolor($tw, $th);
imagecopyresampled($thumb, $image, 0, 0, 0, 0, $tw, $th, $w, $h);
imagedestroy($image);
# How to add Content-Length here, after image resizing?
if (IMAGETYPE_JPEG == $type)
imagejpeg($thumb, null, 75);
else if (IMAGETYPE_PNG == $type)
imagepng($thumb, null, 9);
else if (IMAGETYPE_GIF == $type)
imagegif($thumb, null);
imagedestroy($thumb);
}
?>
Я не прошу, чтобы кто-нибудь выполнял мою работу за меня, просто просил о хороших указателях или фрагментах кода, поскольку у меня нет опыта в этих областях (заголовки + даты) PHP еще.