Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Apache

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Гипотеза относительно серверной переменной 'HTTP_IF_MODIFIED_SINCE'
 
 автор: Владимир55   (30.01.2012 в 12:36)   письмо автору
 
 

Несмотря на множество попыток, никаким образом не удаётся получить значения
$_ENV['HTTP_IF_MODIFIED_SINCE']
$_SERVER['HTTP_IF_MODIFIED_SINCE']

Пытаясь разобраться в проблеме, я пришел к предположению, что:

1. $_ENV['HTTP_IF_MODIFIED_SINCE'] будет пустой всегда, если РНР подключен как модуль Apache, а на хостингах это именно так;
2. $_SERVER['HTTP_IF_MODIFIED_SINCE'] будет всегда пустой, поскольку на любом хостинге заголовки передаются через кеширующий прокси сервер nginx

Это похоже на правду?

  Ответить  
 
 автор: cheops   (30.01.2012 в 12:51)   письмо автору
 
   для: Владимир55   (30.01.2012 в 12:36)
 

Переменной окружения HTTP_IF_MODIFIED_SINCE нет и по умолчанию она не создается - эту переменную вы ввели сами, поэтому за её существование вы отвечаете самостоятельно. Т.е. если у вас нет вот такого .htaccess, никто из серверного хозяйства даже не почешется её создать
RewriteEngine on
RewriteRule ^index.php$ index.php [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}]
Здесь правило устанавливает переменную окружения HTTP_IF_MODIFIED_SINCE только для файла index.php, мне нечем отправить этот заголовок, поэтому у меня переменная пустая, но можно проверить её существование при помощи isset()
<?php
  
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) echo "установлено";
  else echo 
"не установлено";
?>
Вот для index.php будет выведено "установлено", для всех остальных файлов "не установлено". Если серверу от клиента придет HTTP-заголовок If-Modified-Since, то в переменную будет помещено его содержимое.

Еще раз хочу подчеркнуть, нет стандартной переменной окружения HTTP_IF_MODIFIED_SINCE - если её не создать, её не будет.

  Ответить  
 
 автор: Владимир55   (30.01.2012 в 14:52)   письмо автору
 
   для: cheops   (30.01.2012 в 12:51)
 

Еще раз хочу подчеркнуть, нет стандартной переменной окружения HTTP_IF_MODIFIED_SINCE - если её не создать, её не будет.

Совершенно неожиданное открытие!
Я ведь и хостеру о проблеме писал, но он, почему-то, не обратил на это внимание!

Спасибо!

Как полагаете, для контроля достаточно $_SERVER или нужен также и $_ENV ?

По идее, информация у них должна быть одинаковой...

  Ответить  
 
 автор: cheops   (30.01.2012 в 15:00)   письмо автору
 
   для: Владимир55   (30.01.2012 в 14:52)
 

Если вы устанавливаете переменную окружения при помощи модуля Web-сервера или его модуля (в данном случае mod_rewrite), то она должна быть в $_SERVER. Вообще $_SERVER - это переменные окружения сервера, а $_ENV - переменные окружения операционной системы. Они частично совпадают, так как сервер сам половину переменных окружения получает от операционной системы (в общем они не всегда совпадают). Однако, переменные окружения, установленные mod_rewrite лучше искать в первую очередь в $_SERVER.

  Ответить  
 
 автор: Владимир55   (30.01.2012 в 15:15)   письмо автору
 
   для: cheops   (30.01.2012 в 15:00)
 

Придется в .htaccess для каждой страницы делать такую запись, как Вы привели для главной?

Универсального решения нет? Чтобы для всех страниц сайта с расширениями PHP, HTM, HTML?

  Ответить  
 
 автор: cheops   (30.01.2012 в 15:34)   письмо автору
 
   для: Владимир55   (30.01.2012 в 15:15)
 

Нет-нет, приведенный выше .htaccess просто чтобы продемонстрировать, что переменную окружения можно поставить, что она ставится и как это можно проверить факт установки (потому, что проблема на продакшен-хостах остается, вам могут запретить ставить свои переменные окружения). При помощи .htaccess можно создать более универсальное выражение, которое охватит все файлы, например, как-то так
RewriteEngine on 
RewriteRule ^(.*)$ $1 [L, E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}]

  Ответить  
 
 автор: Владимир55   (30.01.2012 в 15:54)   письмо автору
 
   для: cheops   (30.01.2012 в 15:34)
 

Такой .htaccess выдаёт 500 ошибку......

  Ответить  
 
 автор: cheops   (30.01.2012 в 16:28)   письмо автору
 
   для: Владимир55   (30.01.2012 в 15:54)
 

Пробел лишний, попробуйте такой
RewriteEngine on  
RewriteRule ^(.*)$ $1 [L,E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}]

  Ответить  
 
 автор: Владимир55   (30.01.2012 в 16:31)   письмо автору
 
   для: cheops   (30.01.2012 в 16:28)
 

Один ключик мешал, вот так можно?

RewriteEngine on  
RewriteRule ^(.*)$ $1 [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}] 

  Ответить  
 
 автор: cheops   (30.01.2012 в 16:33)   письмо автору
 
   для: Владимир55   (30.01.2012 в 16:31)
 

Можно и так, особенно, если после этого правила больше не будет никаких других правил.

  Ответить  
 
 автор: cheops   (30.01.2012 в 15:29)   письмо автору
 
   для: Владимир55   (30.01.2012 в 14:52)
 

>Я ведь и хостеру о проблеме писал, но он, почему-то, не обратил на это внимание!
Они как правило, не могут знать все особенности серверного ПО, его очень много и оно сложно, да и вопросы у вас не тривиальные :))) Не так часто прикладникам приходится работать на уровне протоколов, поэтому и такие вопросы возникают не часто... вот если хост-провайдер каждый день отвечал на вопросы по разработке серверов, они бы закидали вас ответами и готовым кодом, а так... я бы если бы не знал всех ваших предыдущих вопросов подумал бы "Ну если переменная HTTP_IF_MODIFIED_SINCE начинается с HTTP ежу понятно, что она стандартная (уж больно похожа), надо же никогда до этого не встречал... новая что-ли? Ну век живи, век учись... попробуем ответить на вопрос".

PS Вообще стандарта на переменные окружения нет. Конечно, PATH вы везде найдете (и она скорее всего даже в POSIX прописана), и понятно, что Linux и Windows сами себе стандарты... но переменные окружения - это обычные переменные оболочки, которые вводятся с такой же легкостью, как переменные языка программирования. Какие-то есть заранее, какие-то определяются программами. Windows, например, еще дальше пошел - целый реестр себе этих переменных отрастил :))) Вот переменные окружения - это такой прото-реестр, это то, чем был реестр 30-40 лет назад. Просто в UNIX-ПО это эксплуатируется по сию пору - в UNIX так принято данными между процессами обмениваться. Виртуальная память, отражение в память, которое используется в Windows - это уже более поздние решения 20-летней давности (все же серверное ПО почти сплошь UNIX-разработки).

  Ответить  
 
 автор: Владимир55   (30.01.2012 в 16:40)   письмо автору
 
   для: cheops   (30.01.2012 в 15:29)
 

СПАСИБО!

  Ответить  
 
 автор: Izcian   (03.02.2013 в 22:49)   письмо автору
 
   для: cheops   (30.01.2012 в 15:29)
 

Просто здорово что наткнулся на Ваш диалог, спасибо за разъяснения. Но вот какое дело, после того как я запустил все это хозяйство с этими заголовками, время загрузки страниц очень серьезно увеличилось. Особенно CSS - файлов. Что делать, ума не приложу

  Ответить  
 
 автор: cheops   (04.02.2013 в 22:20)   письмо автору
 
   для: Izcian   (03.02.2013 в 22:49)
 

Ну Rewrite, да, приводит к замедлению скорости обработки... У вас виртуальный хостинг, выделенный сервер?

PS Под новые вопросы лучше все-таки заводить новые темы.

  Ответить  
 
 автор: Sfinks   (30.01.2012 в 20:10)   письмо автору
 
   для: cheops   (30.01.2012 в 12:51)
 

> Переменной окружения HTTP_IF_MODIFIED_SINCE нет
ЕСТЬ!

> и по умолчанию она не создается - эту переменную вы ввели сами
Создается, если сервер передает этот заголовок.

> Еще раз хочу подчеркнуть, нет стандартной переменной окружения HTTP_IF_MODIFIED_SINCE
Еще раз хочу подчеркнуть, ОНА ЕСТЬ в массиве $_SERVER.

  Ответить  
 
 автор: cheops   (31.01.2012 в 11:50)   письмо автору
 
   для: Sfinks   (30.01.2012 в 20:10)
 

Да, перепрятушки, есть в исходных кодах PHP такая переменная окружения, наряду с HTTP_COOKIE2 и HTTP_VIA :))) На Apache ориентировался, поленился в исходный код залезть.

  Ответить  
 
 автор: Владимир55   (31.01.2012 в 12:22)   письмо автору
 
   для: cheops   (31.01.2012 в 11:50)
 

<?php
   
//Ссодержимое массива $_SERVER
Array
(
    [
HTTP_HOST] => домен 
    
[HTTP_X_FORWARDED_FOR] => IP адрес
    
[HTTP_X_SCHEME] => http
    
[HTTP_CONNECTION] => close
    
[HTTP_IF_MODIFIED_SINCE] => Sat29 Oct 1994 19:43:31 GMT
    
[PATH] => /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
    
[SERVER_SIGNATURE] => <address>Apache/2 домен Port 80</address>

    [
SERVER_SOFTWARE] => Apache/2
    
[SERVER_NAME] => домен
    
[SERVER_ADDR] => 127.0.0.1
    
[SERVER_PORT] => 80
    
[REMOTE_ADDR] => IP адрес 
    
[DOCUMENT_ROOT] => /home/имя_пользователя/domains/домен.ru/public_html
    
[SERVER_ADMIN] => support@хххх.ru
    
[SCRIPT_FILENAME] => /home/имя_пользователя/domains/домен.ru/public_html/имя_скрипта.php
    
[REMOTE_PORT] => 50327
    
[GATEWAY_INTERFACE] => CGI/1.1
    
[SERVER_PROTOCOL] => HTTP/1.0
    
[REQUEST_METHOD] => GET
    
[QUERY_STRING] => 
    [
REQUEST_URI] => /имя_скрипта.php
    
[SCRIPT_NAME] => /имя_скрипта.php
    
[PHP_SELF] => /имя_скрипта.php
    
[REQUEST_TIME] => 1327932673
)


Зато теперь ясно, как создать любую переменную окружения, какая понадобится!

  Ответить  
 
 автор: Sfinks   (30.01.2012 в 20:03)   письмо автору
 
   для: Владимир55   (30.01.2012 в 12:36)
 

Я чет не понял!
Я в игноре или мое описание в теме http://softtime.ru/forum/read.php?id_forum=5&id_theme=84713&page=1 не заметно?
Все что там написано было обнаружено на локале, но сейчас я проверил на хостинге и все актуально и для хостинга. Вот заголовки в подтверждение:
GET /477/23188/thumb.css HTTP/1.1
Host: site.info
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.24) Gecko/20111103 Firefox/3.6.24
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,text/vnd.wap.wml;q=0.6
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
If-Modified-Since: Sun, 15 Jan 2012 23:48:14 +0000
Cache-Control: max-age=0

HTTP/1.1 304 Not Modified
Date: Mon, 30 Jan 2012 16:00:45 GMT
Server: Apache/2
Connection: Keep-Alive
Keep-Alive: timeout=1, max=100
Vary: Accept-Encoding,User-Agent
_________
P.S. Cheops, сделайте в форуме тег [выделить красным жирным крупным шрифтом] =((( Все так подробно расписал и как и не писал все равно!

  Ответить  
 
 автор: Владимир55   (31.01.2012 в 00:52)   письмо автору
 
   для: Sfinks   (30.01.2012 в 20:03)
 

Я в игноре или мое описание в теме http://softtime.ru/forum/read.php?id_forum=5&id_theme=84713&page=1 не заметно?

Ваше описание и замечено, и изучено, и использовано.

Сорри, что не написал благодарности сразу - для осмысления требуется время!

Спасибо Вам за совет и помощь!

  Ответить  
 
 автор: Sfinks   (31.01.2012 в 09:12)   письмо автору
 
   для: Владимир55   (31.01.2012 в 00:52)
 

Просто не понятно, как "прочитав и изучив" можно прийти к умозаключению:
> 2. $_SERVER['HTTP_IF_MODIFIED_SINCE'] будет всегда пустой, поскольку.....

Чтоб понятней было, опишу как выловить на том же примере, но с цитатами:
Запрос:
http://site.info/154/5059/thumb.css

Редирект в .htaccess:
RewriteEngine On
RewriteRule ^(\d+)/(\d+)/thumb\.css$ thumb.css.php?c=$1&g=$2 [L]

Фрагмент кода отвечающий за кеширование:
<?
  header
("Content-type: text/css");
  
header("Last-Modified: ".date("r",$last_mod_stamp));
  
header("Cache-Control: private, max-age=2592000, pre-check=605000");
Здесь $last_mod_stamp определяется в коде ранее, по дате модификации файла на который ссылается результирующий CSS. Вообще самая большая проблема с реализацией ответа 304 у вас будет заключаться именно в определении этой переменно. Мне, например, т.к. файл, дату модификации которого нужно узнать, находится удаленно, чтоб не дергать HTTP при каждом обращении, пришлось создать новую таблицу в БД и поменять много где еще код, чтоб информация в этой таблице была актуальна. И вообще для каждого блока сайта алгоритм определения этой переменной будет сложным и индивидуальным.

Далее, когда страница кеширована браузером и вы нажимаете "обновить" (ну или яндекс перезагружает уже загруженную ранее страницу), отправляется этот неуловимый заголовок. И вот фрагмент кода, отвечающий за отслеживание этого заголовка:
<?
  
if(isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]))
    if(
$since_stamp strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]))
      if(
$since_stamp >= $last_mod_stamp){
        
header("HTTP/1.1 304 Not Modified");
        exit;
      }
Располагается он между определением переменной $last_mod_stamp и выводом заголовков кеширования.
______
P.S. Если вы тестируете в Опере, то ниче не сработает. Опера никогда не отправляет этот заголовок.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования