sidorenkoda
@sidorenkoda
Программист, верстальщик, руководитель проектов

Как заставить htaccess проверять наличие файла по пути, который надо получить(путь) после распаршивания урла mod rewrite?

Извиняюсь, если вопрос звучит путано, но прочитав разъяснение ниже Вы поймете о чем идет речь.
Есть файл в собственном движке .htaccess
######################
RewriteEngine on
DirectoryIndex index.php
Options +FollowSymlinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule [%,a-zA-Z0-9/-/+/()]+[.]{1}[php|html?] index.php
# если картинка, то мод реврайт кидает на скрипт,
# обрабатывающий изображения
RewriteRule ximage/[a-zA-Z\_\-0-9\/]+[.]{1}[jpg|jpeg?] ximg.php
######################
Суть его в том, что если при обращении на хостинг по пути:

{host}/ximage/1600/1600/upload/models/07871915a8107172b3b5dc15a6574ad3.jpg

он перекидывает запрос на ximg.php.
А ximg.php делает ресайз изображения 1600 на 1600 (разумеется, цифры могут быть любыми, поддерживаемыми скриптом)

Сам скрипт в зависимости от параметров делает изображению ресайз или кроп.
Но проблема вот в чем.
Он всегда проверяет кеш, и если он есть, то отдает его средствами PHP!
header('Content-type: ' . $mime);
if ( !is_file($_SERVER['DOCUMENT_ROOT'] . $output) ) {
$file = resize($input, $_SERVER['DOCUMENT_ROOT'] . $output, $h, $w, $ext);
} else {
readfile($_SERVER['DOCUMENT_ROOT'] . $output);
}
Что очень сильно увеличивает нагрузку на сервер.
Можно ли проверку на существования файла повесить на .htaccess и сделать так, чтобы он не обращался к скрипту, если файл есть на сервере.

Альтернативным решением будет заголовок, заставляющий кешировать изображение на 2 дня с момента его создания. Но хотелось бы именно средствами Apache (mod_rew) принимать решение о выдаче кешированной картинки.

Спасибо, что дочитали до этого места =)

Для интересующихся привожу сам скрипт (надеюсь кому-то будет полезен, но учтите, что у него нет защиты от перебора высоты):

<?php
$goodExtArr = array(
'jpg' => 1,
'jpeg' => 1,
'png' => 1,
'gif' => 1
);
$goodSizes = [

200 => [
600 => 1,
500 => 1
],

400 => [
600 => 1,
500 => 1
],
600 => [
600 => 1,
500 => 1
],
800 => [
600 => 1,
500 => 1
],
1200 => [
600 => 1,
500 => 1
],
1600 => [
600 => 1,
500 => 1
],
];
$_SERVER['REQUEST_URI'] = str_replace('?10x15crop', '', $_SERVER['REQUEST_URI']);
$input = $_SERVER['REQUEST_URI'];
$input = explode('/', $input);
if ( $input[1] == 'ximage' ) {
$w = intval($input[2]);
$h = intval($input[3]);
$fname = $input[count($input) - 1];
unset($input[0]);
unset($input[1]);
unset($input[2]);
unset($input[3]);
$path = implode('/', $input);
if ( substr($path, 0, 7) != 'upload/' && strpos($path, '../') ) {
die('gg');
}
if ( !isset($goodSizes[$w]) ) {
die('bad size');
}
$ext = explode('.', $path);
$ext = $ext[count($ext)-1];
#$ext = explode('?', $ext);
#$ext = $ext[0];
if ( !isset($goodExtArr[$ext]) ) {
die('bad ext');
}
}
$output = '/upload/img_cache/' . $w . '_' . $h . '_' . md5($path) . $fname;
$input = $_SERVER['DOCUMENT_ROOT'] . '/' . $path;
if ( !is_file($_SERVER['DOCUMENT_ROOT'] . $output) ) {
resize($input, $_SERVER['DOCUMENT_ROOT'] . $output, $h, $w, $ext);
} else {
#$header('Location: ' . $output);
}
$date = date("U");
$date = 1418906326 + 3600*365 * 5;
$date = 1418906326 - 2000;
#echo $date;
#die;
$dt_tmp=getdate($date);
header("Expires: " . gmdate("D, d M Y H:i:s",
$date-(86400*($dt_tmp["wday"]-8))) . " GMT");
header("Cache-control: public");

#$a = file_get_contents($_SERVER['DOCUMENT_ROOT'] . $output);
if ( $ext == 'jpg' || $ext == 'jpeg' ) {
header('Content-type: image/jpeg');
readfile($_SERVER['DOCUMENT_ROOT'] . $output);
#echo $a;
} else if ( $ext == 'png' ) {
header('Content-type: image/png');
readfile($_SERVER['DOCUMENT_ROOT'] . $output);
#echo $a;
} else if ( $ext == 'jpg' ) {
header('Content-type: image/gif');
readfile($_SERVER['DOCUMENT_ROOT'] . $output);
#echo $a;
}
function resize($input, $output, $height, $width, $ext) {
$ext = '.' . $ext;
if (file_exists($output)) {
unlink($output);
}
$size = getimagesize($input);
$w = $size[0];
$h = $size[1];
if ($h < $height) {
$a = 1;
$newy = $h;
} else {
$a = $height / $h;
$newy = $height;
}
$newx = $a*$w;
if ($newx > $width) {
$a = $width / $newx;
$newx = $width;
$newy = $newy * $a;
}


if (($ext == ".jpg") || ($ext == ".jpeg") || ($ext == ".png") || ($ext ==".gif")) {
if (($ext == ".jpg") || ($ext == ".jpeg")) {
$source = imagecreatefromjpeg($input) or die('Cannot load original JPEG');
}
if ($ext ==".gif") {
$source = imagecreatefromgif($input) or die('Cannot load original GIF');
}
if ($ext == ".png") {
$source = imagecreatefrompng($input) or die('Cannot load original PNG');
}
$target = imagecreatetruecolor($newx, $newy);
imagefill($target, 0,0, '0');
imagecopyresampled($target, $source, 0,0, 0,0, $newx, $newy, $size[0], $size[1] );
if (($ext == ".jpg") || ($ext == ".jpeg")) imagejpeg($target, $output, 100);
if ($ext ==".gif") imagegif($target, $output, 85);
if ($ext == ".png") imagepng($target, $output, 0);
imagedestroy($target);
imagedestroy($source);
} else {
copy($input, $output);
}
}
function p($a) {
echo '';
print_r($a);
echo '';
}
?>
  • Вопрос задан
  • 3190 просмотров
Решения вопроса 1
@Arik
давно не работал с .htaccess, а если просто проверить перед правилом есть такой файл или нет и пути совпадают или различаются?
Т.е. когда скрипт нарезает он реально ложит по адресу:
{host}/ximage/1600/1600/upload/models/07871915a8107172b3b5dc15a6574ad3.jpg ?

# если картинка, то мод реврайт кидает на скрипт,
# обрабатывающий изображения
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ximage/[a-zA-Z\_\-0-9\/]+[.]{1}[jpg|jpeg?] ximg.php
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы