0,0
рейтинг
13 октября 2012 в 05:49

Разработка → Попытка номер раз создать почти идеальный htaccess tutorial

    - Google выше ранжирует сайты, которые загружаются быстрее.
    - Если на eBay или Amazone увеличить время загрузки страниц на 9% они теряют 1% прибыли.
    - Сделать свой сайт быстрее, чтобы сэкономить на клиентском трафике и на числе обращений к серверу.


.htaccess — наш герой


Профессионалы знают, что такое htaccess.
Тем кто собираются уйти с народ.ру на php-хостинг только предстоит узнать, что это такое.
Те кто только что установил свои первые jooml'у или wordpress срочно должны узнать о нашем герое — htaccess

Зачем нам .htaccess ?


Представьте, что вы купили себе хостинг и кажется, почти обрели счастье. Но однажды (а может быть дважды, а может и трижды) ваш сайт перестает отвечать на запросы. Начинает медленно грузиться и вообще вести себя странно. А виртуальный хостинг это такая хитрая штука, что помимо вашего сайта на этом сервере находится ещё два десятка других сайтов. Все они разные по мощности, организованности и трафику. И когда ваш сосед по случайности, а может и умыслу запускает на своем хостинге сложные или избыточные в алгоритмах скрипты, это отзывается и на вас.

Или другой пример. Скажем ваш ресурс начинает набирать популярность, но переезжать на выделенный сервер ещё рано, а мощностей VPS уже не хватает. Вас очень может выручить htaccess.

А ещё htaccess может решить некоторые вопросы с безопасностью вашего сайта.

А ещё…

Хочу идеальный .htaccess !


Оказывается в интернете много различной противоречивой информации относительно того как использовать .htaccess. Пришлось долго и нудно экспериментировать, чтобы понять что истинно, а что ложно. В большинстве случаев авторы советов в своих блогах забывают упомянуть, что для работы определенных условий нужен тот или иной модуль Апача.
Впрочем хватит слов, пора к делу. Попробуем создать почти идеальный .htaccess

1. Первой строкой задаем основные опции:

Options All -ExecCGI -Indexes -Includes +FollowSymLinks

Использовать опции очень удобно, когда у вас нет доступа к конфигурированию Апача или нужны разные настройки Апача для разных сайтов на одном сервере.

Опция -ExecCGI запрещает запуск CGI скриптов. Лучше разрешить только для конкретных папок. Повысит безопасность.
Опция -Indexes запрещает показывать содержимое каталогов, если в них нет индексного файла. На виртуальном хостинге обычно включена по умолчанию. Изменив минус на плюс +Indexes можете наоборот разрешить просмотр содержимого каталога (или каталогов).
Опция -Includes запрещает SSI. Если не знаете, что это — запрещайте (Можно поЯндексировать(!) по запросу Server Side Include если хотите узнать об этом побольше). Можно использовать опцию IncludesNOEXEC, которая разрешит использовать SSI без запуска скриптов.
Опция +FollowSymLinks позволяет использовать символические ссылки на файлы или каталоги, не находящиеся в пределах корня вашего сайта.

Примечание
Вы можете использовать htaccess с разными настройками для разных каталогов. В корне сайта вы можете объявить -Indexes, а в избранных каталогах создать ещё один файл .htaccess и в нем объявить +Indexes. Помните, что действие опций htaccess распространяет сверху вниз по дереву каталогов до самой глубокой вложенности, пока не будут отменены другим htaccess.

Необязательно полностью перечислять все опции в дочерних .htaccess если они не изменяются. Достаточно указать (переназначить) только те опции и директивы, которые изменяются. Остальные опции также унаследуются от родителя.

Пример
Скажем, у вас есть вот такой путь /site/folder_one/subfolder/other/
В файле /site/.htaccess вы указываете:
Options  -Indexes
Allow from all

В файле /site/folder_one/.htaccess указываете:
Deny from all

В файле /site/folder_one/subfolder/.htaccess указываете:
Options  +Indexes
Allow from all

Получиться вот что:
В папке site будут показываться файлы любого содержания, если только к ним напрямую обратиться. Или индексный файл, если не явного обращения к одному из файлов. В случае отсутствия индексного файла получена 403 ошибка.
К папке folder_one доступ закрыт. Даже если знать имя файла и набрать его в адресной строке в ответ сервер вернет ошибку 403.
Папка subfolder разрешена для обращений по прямому адресу или же в случае отсутствия индексного файла покажет содержимое каталога. Эти же права распространяться и на папку other.
Если убрать файл ,htaccess из папки folder_one, то она унаследует права от родительской site.

2. Немного SEO (куда же без него)

<IfModule mod_rewrite.c>
	RewriteEngine on
	RewriteBase /
	RewriteCond %{HTTP_HOST} ^black-web
	RewriteRule (.*) http://www.black-web.ru/$1 [R=301,L]
	RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
	RewriteRule ^index\.php$ http://www.black-web.ru/ [R=301,L]
</IfModule>

Обязательно не забыть про условие <IfModule mod_rewrite.c>. Не окажись у хостера данного модуля и ваш сайт станет выдавать 500-ую ошибку. Данный конкретный модуль входить в сборку Апача по-умолчанию. Ну а вдруг… Хостеры и их админы бывают всякие.

В данной части пользы больше для SEO. Модуль rewrite как следует из его названия занимается перенаправлениями (привет Кэпу).

В этой части файла мы указали две склейки: мы склеили ваш_сайт и www.ваш_сайт Даже если пользователь наберет ваш сайт без WWW его перебросить 301 редериктом на www.ваш_сайт.
А также мы избавились /index.php в строке запроса. Если пользователь наберет www.ваш_сайт/index.php его перебросит (снова 301 редериктом) на www.ваш_сайт.
Теперь поисковики не будут путаться между www и не будут дублировать главную страницу в результатах индексирования вашего сайта. Гуглим СЕО склейки домена, если не понимаете зачем это нужно.

3. Кто в папке главный?

Если у вас папке есть файлы index.html и index.php (не знаю, зачем и кому такое было нужно, но не раз видел такое) то как указать серверу кто их них более индексный?

DirectoryIndex index.php

А ещё можно там указать скажем roosso.php и тогда набрав в строке запроса адрес сайт.бла/бла/бла/ вы увидете не index, а roosso

4. Ещё настройки…

<IfModule mod_setenvif.c>
	SetEnv TZ Europe/Moscow
</IfModule>
ServerSignature Off
AddDefaultCharset UTF-8

Первая строчка устанавливает часовой пояс. Например в Apache 2.22.22 был баг связанный с этой опцией. Функции времени в php не работали, пока не установишь часовой пояс.

Вторая строка это подпись сервера. Вы их не раз видели на всяких системных страницах типа 500ой ошибки или 403ей. Обычно там какая-нибудь техническая информация и почта вебмастера. Я предпочитаю даже в таких мелочах скрывать данные о софте на сервере. Коллеги параноики меня поддержат.

Угадайте, что делает третья строка?

5. Когда нет доступа к php.ini

С помощью .htaccess мы также можем управлять рядом настроек PHP. На виртуальном хостинге, как правило, нет возможности изменять настройки php.ini. Чаще всего этого и не требуется. Но все же есть ряд опций контроль над которыми может нам быть полезен. Например, увеличить лимит на загрузку файлов, или лимит передачи данным методом POST.

<ifModule mod_php.c>
  php_value	upload_max_filesize	32M
  php_value	post_max_size		10M
  php_value	default_charset utf-8
  php_value	max_execution_time 200
</ifModule>

Первая строчка разрешить загружать файлы размером до 32 Мегабайт. По умолчанию в php обычно это значение 8 или 16 мегабайт.
Второй строкой разрешаем постинг объемом до 10 мегабайт. По умолчанию это значение обычно 2 Мегабайта.
Третья строка устанавливает кодировку по используемую вашими скриптами. По своей сути она дублирует строку: «AddDefaultCharset UTF-8». Но я чаще прибегаю к установке кодировки именно через php.
Четвертой строкой изменяем лимит времени выделенный на выполнение скрипта. По умолчанию он обычно равен 30 секундам. Но иногда для выполнения каких нибудь сложных обработок требуется больше времени.

6. Типы файлов. Ловкость рук и ни какого мошенничества.

В моей практике случалось пару раз, что после какого либо обновления провайдером софта, слетали типы файлов. Хотя такое редко. За 10 лет, всего два случая. Но иногда мне нужно было заставить html работать как php. А иногда требуется научить апач различать типы файлов, которые ему неизвестно. (Как оказалось Апачу вообще мало что известно из редких типов файлов.) В такой ситуации нас спасет следующий код:

AddHandler application/x-httpd-php .html
AddHandler cgi-script .pl .py .jsp .asp .htm .shtml .sh .cgi
AddType application/x-javascript .js
AddType text/css .css
AddType text/xml .xml
AddType application/octet-stream .doc .mov .avi .pdf .xls 
# ForceType application/x-httpd-php


Первая строчка позволит нашим php файлам иметь расширение html, но выполняться как php. Полезно бывает во многих случаях. А в старые добрые когда поисковики индексировали ЧПУ лучше, такая строчка всегда приходила на выручку.
Мы можем переназначить, добавить или подменить любые типы файлов под удобные нам разрешения.

Интересный трюк
Кстати, вы можете легко написать к примеру вот такую строку:

AddHandler application/x-httpd-php .i

Потом переименовать все ваши файлы, изменив расширение на .i (не забыв конечно про ссылки) и адреса файлов у вас на сайте будут не сайт.мой/index.php?uri а сайт.мой/index.i?uri

Например я пишу
AddHandler application/x-httpd-php .roosso

и создаю в корне своего сайта файл alex.roosso внутри обычный php код. Это вроде как страница обо мне любимом. И в адресной строке она будет выглядеть как www.black-web.ru/alex.roosso (ссылка рабочая, можете посмотреть что это так).

Второй строкой указано, какие расширения файлов должны выполняться как cgi скрипты.

Третья, четвертая и пятая строки, на всякий случай уточняют мим-тип файлов с разрешением css, js, xml. Не путайте с присвоением заголовка в ответе сервера на запрос, как это сделано в первых двух строках.

Шестая строчка это участка, нужна если на вашем сайте есть скачиваемый для пользователей контент. Если добавить эту строку, то при обращении к данным файлам им будет предлагаться скачать их на компьютер, а не как это сейчас в современным браузерах куча плагинов, которые даже word открывают в браузере.

Седьмую строку я закомментировал. Это строчка в принудительно-добровольном порядке, будет все файлы с вашего сервера запустить как php. Её лучше использовать лишь в отдельных папках, при необходимости.

7. Знают взрослые и дети, что архивы меньше весят…

Полезно, когда ваши страницы загружаются быстрее. Поэтому люди и придумали архивировать файлы. А потом они ещё подумали и решили, что архивировать можно и страницы на сайтах и картинки. Причем делать это незаметно для пользователя, но существенно снижать трафик и ускорять загрузку страниц. Волшебные слова прозвучали, теперь обсудим, как это можно сделать.

У Апача есть два модуля сжатия. Оба не являются модулями по умолчанию, поэтому необязательно могут присутствовать у вашего провайдера. Но как показала практика у 99% провайдеров один из них стоит. Наиболее распространен mod_deflate. Чтобы его с помощью сжимать весь контент на вашем сайте добавьте в .htaccess следующие строки:

<ifModule mod_deflate.c>
	AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript
</ifModule>

Как видите мы должны перечислить mime type файлов, которые следует подвергать сжатию. Сюда можно добавить и видео и картинки, но толку это даст мало. Потому что jpeg или gif уже сами по себе являются сжатыми форматами. Также как avi или flv. Вы фактически нечего не выиграете указав их.

Второй менее популярный модуль это mod_gzip, Чтобы включить сжатие с его помощью добавьте вот такие строчки:

<IfModule mod_gzip.c>
	mod_gzip_on         Yes
	mod_gzip_dechunk    Yes
	mod_gzip_item_include file		\.(html?|txt|css|js|php|pl)$
	mod_gzip_item_include mime		^text\.*
	mod_gzip_item_include mime		^application/x-javascript.*
	mod_gzip_item_exclude mime		^image\.*
	mod_gzip_item_exclude rspheader	^Content-Encoding:.*gzip.*
</IfModule>

Данный модуль умеет работать с масками, что несомненно большой плюс. Да и синтаксис у него куда более гибкий чем у предыдущего. Но используют его реже. А по сжатию я даже не берусь судить, который из модулей лучше. Я сильной разницы не заметил при тестах.

8. А ещё быстрее можно?

Можно. Если применить кеширование страниц. У кеширования есть и плюсы и минусы, поэтому подходить к этому вопросу надо подготовившись. Для динамически обновляющегося сайт каждый 2-3 минуты, например популярного форума, нужно учесть, что пользователь должен видеть актуальную информацию. Но у любого сайт есть контент, который более или менее статичен. Например те же картинки, или файлы стилей. Поэтому нам потребуется по разному использовать кеширование различного содержимого на сайте. В html разметки мы всегда можем использовать meta теги. И через php мы может устанавливать заголовки ответа сервера. Остается вопрос, как быть с css, js, image и т.д. и т.п.

Помочь нам в этом могут два модуля: mod_headers и mod_expires которые могут установить заголовки в ответ сервера и подсказать вашему браузеру, что и как нужно кешировать. Один из модулей обычно стоит у провайдера, но как и в случае с любым модулем, который не входит в стандартную сборку Апача, 100% гарантии никто вам не даст. Поэтому снова во избежание 500й ошибки указывает условия для каждого из модулей.

<ifModule mod_headers.c>
	#кэшировать html и htm файлы на один день
	<FilesMatch "\.(html|htm)$">
		Header set Cache-Control "max-age=43200"
	</FilesMatch>
	#кэшировать css, javascript и текстовые файлы на одну неделю
	<FilesMatch "\.(js|css|txt)$">
		Header set Cache-Control "max-age=604800"
	</FilesMatch>
	#кэшировать флэш и изображения на месяц
	<FilesMatch "\.(flv|swf|ico|gif|jpg|jpeg|png)$">
		Header set Cache-Control "max-age=2592000"
	</FilesMatch>
	#отключить кэширование
	<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$">
		Header unset Cache-Control
	</FilesMatch>
</IfModule>

Вот такой синтаксис у mod_headers. Думаю по комментариям ясно что к чему.
В данной секции я отключил кеширование php файлов. Хотя по моему мнению небольшой временной интервал кеширования им не повредит. 5-30 секунд, это интервал времени, за который мало что меняется. А многие пользователи любят пользоваться клавишей back (вернуться назад). Чтобы не загружать им страницу второй раз, а подхватить её из кеша, разумный интервал кеширования все же уместен.

Во второй секции где идут условия для mod_expires я именно так и делаю — для php ставлю небольшой интервал кеширования.

<ifModule mod_expires.c>
	ExpiresActive On
	#по умолчанию кеш в 5 секунд
	ExpiresDefault "access plus 5 seconds"
	#кэшировать флэш и изображения на месяц
	ExpiresByType image/x-icon "access plus 2592000 seconds"
	ExpiresByType image/jpeg "access plus 2592000 seconds"
	ExpiresByType image/png "access plus 2592000 seconds"
	ExpiresByType image/gif "access plus 2592000 seconds"
	ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
	#кэшировать css, javascript и текстовые файлы на одну неделю
	ExpiresByType text/css "access plus 604800 seconds"
	ExpiresByType text/javascript "access plus 604800 seconds"
	ExpiresByType application/javascript "access plus 604800 seconds"
	ExpiresByType application/x-javascript "access plus 604800 seconds"
	#кэшировать html и htm файлы на один день
	ExpiresByType text/html "access plus 43200 seconds"
	#кэшировать xml файлы на десять минут
	ExpiresByType application/xhtml+xml "access plus 600 seconds"
</ifModule>


9. Правила вежливого тона…

В процессе модернизации своего сайта, мы часто оставляем хвосты ввиде ссылок, которые ведут на страницы, которые мы удалили. Иногда такие ссылки идут с других сайтов или из поисковых систем. Чтобы не терять пользователей вежливым тоном считается иметь собственные страницы для различного типа ошибок. Включая даже ошибки сервера. Например стандартное сообщение о 500й ошибки очень скучное и мрачное, и вряд ли вызовет у пользователя желание посетить вашу страницу ещё раз. Но в htaccess есть приемы, которые могут сделать даже эту страницу приветливей.

# Bad Rquest
ErrorDocument 400 /400.html
# Authorization Required
ErrorDocument 401 /401.html
# Forbidden
ErrorDocument 403 /403.html
# Not found
ErrorDocument 404 /404.html
# Method Not Allowed
ErrorDocument 405 /405.html
# Request Timed Out
ErrorDocument 408 /408.html
# Request URI Too Long
ErrorDocument 414 /414.html
# Internal Server Error
ErrorDocument 500 /500.html
# Not Implemented
ErrorDocument 501 /501.html
# Bad Gateway 
ErrorDocument 502 /502.html
# Service Unavailable 
ErrorDocument 503 /503.html
# Gateway Timeout
ErrorDocument 504 /504.html

Для 400-х ошибок можно использовать и динамические страницы на php. А вот для 500 лучше сделать на html и js. Это часть ошибок обычно связана с ошибками сервера (в большинстве случаев) и php или cgi как правило в такой ситуации не работают.

Если вам лень делать столько страниц устанавливайте страницей ошибок главную страницу своего сайта или карту сайта.

Все это вы делаете исключительно для людей. Поисковым роботам плевать на то есть у вас страницы ошибок или нет. Они видят ответ сервера с кодом ошибки и блокируют вашу страницу в поиск. Так что имейте ввиду, это не панацея. Это лишь вежливость к вашей аудитории и имидж вашего сайта.

10. Подведем итог

Знатоки понимают, что в этой статье описано далеко не все. Я коснулся здесь лишь поверхности «айсберга». На самом деле возможности .htaccess куда много обширней, чем описано в статье. Но я и не преследовал целью перевести манаул по htaccess на русский язык. Всего чего я хотел это создать небольшой костяк файла .htaccess для тех, кто только приступил к изучению данного вопроса, чтобы сэкономить их время на поисках информации по сети.

В результате всех манипуляций у нас должен был получить файл следующего содержания:

Options All -ExecCGI -Indexes -Includes +FollowSymLinks

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /
    RewriteCond %{HTTP_HOST} ^black-web
    RewriteRule (.*) http://www.black-web.ru/$1 [R=301,L]
    RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
    RewriteRule ^index\.php$ http://www.black-web.ru/ [R=301,L]
</IfModule>

DirectoryIndex index.php

<IfModule mod_setenvif.c>
	SetEnv TZ Europe/Moscow
</IfModule>
ServerSignature Off
#AddDefaultCharset UTF-8
<ifModule mod_php.c>
	php_value	upload_max_filesize	32M
	php_value	post_max_size		10M
	php_value	default_charset utf-8
	php_value	max_execution_time 200
</ifModule>
AddHandler application/x-httpd-php .html
AddHandler cgi-script .pl .py .jsp .asp .htm .shtml .sh .cgi
AddType application/x-javascript .js
AddType text/css .css
AddType text/xml .xml
AddType application/octet-stream .doc .mov .avi .pdf .xls 
# ForceType application/x-httpd-php

<ifModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript
</ifModule>

<IfModule mod_gzip.c>
    mod_gzip_on         Yes
    mod_gzip_dechunk    Yes
    mod_gzip_item_include file		\.(html?|txt|css|js|php|pl)$
    mod_gzip_item_include mime		^text\.*
    mod_gzip_item_include mime		^application/x-javascript.*
    mod_gzip_item_exclude mime		^image\.*
    mod_gzip_item_exclude rspheader	^Content-Encoding:.*gzip.*
</IfModule>

<ifModule mod_headers.c>
    #кэшировать html и htm файлы на один день
    <FilesMatch "\.(html|htm)$">
        Header set Cache-Control "max-age=43200"
    </FilesMatch>
    #кэшировать css, javascript и текстовые файлы на одну неделю
    <FilesMatch "\.(js|css|txt)$">
        Header set Cache-Control "max-age=604800"
    </FilesMatch>
    #кэшировать флэш и изображения на месяц
    <FilesMatch "\.(flv|swf|ico|gif|jpg|jpeg|png)$">
        Header set Cache-Control "max-age=2592000"
    </FilesMatch>
    #отключить кэширование
    <FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$">
        Header unset Cache-Control
    </FilesMatch>
</IfModule>

<ifModule mod_expires.c>
    ExpiresActive On
    #по умолчанию кеш в 5 секунд
    ExpiresDefault "access plus 5 seconds"
    #кэшировать флэш и изображения на месяц
    ExpiresByType image/x-icon "access plus 2592000 seconds"
    ExpiresByType image/jpeg "access plus 2592000 seconds"
    ExpiresByType image/png "access plus 2592000 seconds"
    ExpiresByType image/gif "access plus 2592000 seconds"
    ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
    #кэшировать css, javascript и текстовые файлы на одну неделю
    ExpiresByType text/css "access plus 604800 seconds"
    ExpiresByType text/javascript "access plus 604800 seconds"
    ExpiresByType application/javascript "access plus 604800 seconds"
    ExpiresByType application/x-javascript "access plus 604800 seconds"
    #кэшировать html и htm файлы на один день
    ExpiresByType text/html "access plus 43200 seconds"
    #кэшировать xml файлы на десять минут
    ExpiresByType application/xhtml+xml "access plus 600 seconds"
</ifModule>

# Bad Rquest
ErrorDocument 400 /400.html
# Authorization Required
ErrorDocument 401 /401.html
# Forbidden
ErrorDocument 403 /403.html
# Not found
ErrorDocument 404 /404.html
# Method Not Allowed
ErrorDocument 405 /405.html
# Request Timed Out
ErrorDocument 408 /408.html
# Request URI Too Long
ErrorDocument 414 /414.html
# Internal Server Error
ErrorDocument 500 /500.html
# Not Implemented
ErrorDocument 501 /501.html
# Bad Gateway 
ErrorDocument 502 /502.html
# Service Unavailable 
ErrorDocument 503 /503.html
# Gateway Timeout
ErrorDocument 504 /504.html


11. Послесловие.

Я старался не спешить в написании статьи и на это ушли почти сутки. Но все же где то я мог допустить ошибки в орфографии или пунктуации. Прошу не казнить, а миловать. А лучше писать в личку, чтобы я поправил ошибки.

И напоследок для любителей экспериментов несколько строк .htaccess. Сужу по своему опыту — на практике знания усваиваются лучше чем в теории.
Разные интересные примеры
# SECURE ____________________
<IfModule mod_ssl.c>
	SSLOptions +StrictRequire
	SSLRequireSSL
	SSLRequire %{HTTP_HOST} eq "black-web.ru"
</IfModule>
<IfModule mod_rewrite.c>
	RewriteCond %{HTTPS} !on
	RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</IfModule>

# HOTLINKING ________________
<IfModule mod_rewrite.c>
	RewriteCond %{HTTP_REFERER} !^$
	RewriteCond %{HTTP_REFERER} !^http://([ -a-z0-9]  \.)?black-web\.ru [NC]
	RewriteRule \.(gif|jpe?g|png)$ - [F,NC,L]
</IfModule>

# REDIRICT __________________
Redirect 301 /index.html /index.php
<IfModule mod_rewrite.c>
	RewriteRule ^news/([^/\.]+)/?$ news.php?news=$1 [L]
	RewriteRule ^(.*\.((js)|(css)))$ plugin/GzipFile.php?file=$1
	RewriteRule \.css$ plugin/GzipFile.php?file=$1
	RewriteRule \.js$ plugin/GzipFile.php?file=$1
</IfModule>
RedirectMatch 301 /blog(.*) http://www.black-web.ru/$1


P.S.
… Для тех у кого всё получилось, идём на www.webpagetest.org мерять красоту до и после.
Andrey_Zentavr
Кому надо берите полностью готовый .htaccess здесь
Данный файл показал самую высокую производительность на тестах.
Также там куча всего закомментировано о чем я не упомянул в статье и что может пригодиться в тех или иных случаях.
Александр Белов // alex Roosso @Roosso
карма
29,2
рейтинг 0,0
PHP Coder
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (77)

  • +3
    Объясните лучше это ваше высказывание:
    Если на eBay или Amazone увеличить скорость загрузки страниц на 9% они теряют 1% прибыли.

    Почему теряет, если скорость — увеличить?
    • +1
      Слово скорость и время перепутал.
      Спасибо. Исправлю…
      • +2
        Чёрт — опечатка, а я всю статью внимательно перечитывал, чтобы понять, в чём подвох :)
  • 0
    А я бы бил за использование htaccess, как ни крути это оверхед и костыль, причем костыль привязаный к 1 веб-серверу — апачу. В современном мире нельзя привязывать продукт к 1 серверу
    • +2
      Костыль если у тебя хотя бы VPS и уж тем более VDS
      Но на виртуальном хостинге, к сожалению без данного костыля жить в разы труднее.
      • +1
        >> Костыль если у тебя хотя бы VPS и уж тем более VDS

        А расскажите, пожалуйста, в чём разница между VPS и VDS?:)
        • 0
          Вопрос с подвохом?
          • 0
            Вопрос как вопрос — в чём разница между VPS и VDS?
            • 0
              Я спросил, потому что мне показалось, что вы пытаетесь подначить меня своим вопросом.
              Если вам и правда интересно, по большому счету почти никакой. В первом случае железо виртуальное, во втором реальное. (хотя я не уверен, что это стандартное разделение… но хостеры у нас обычно разделяют такие вещи)
              • 0
                На самом деле, технической разницы под этими двумя терминами нет никакой. Просто так сложилось, что «у нас» (СНГ и пр) принято виртуальный сервер называть VDS, а «у них» — VPS.

                Всё остальное — лишь домыслы и попытки неумелого маркетинга некоторых «хостеров» :)
                • 0
                  Ну собственно пост для РФ.
                  А неумелый маркетинг у нас по всюду.

                  Насколько я знаю, принципе везде таков: VPS дают минимальные конфига, а под VDS конфиги помощнее.
                  Наверное все из-за волшебного слова Dedicated во второй аббревиатуре.

                  Хотя некий процент VDS называет выделенные серверка (непонятно тогда причем тут Virtual… Но я уже давно смирился с Рашей) а под VPS виртуальные.
                  • +1
                    > Хотя некий процент VDS называет выделенные серверка (непонятно тогда причем тут Virtual…

                    [sarcasm]VERY Dedicated же....:) [/sarcasm]
                • +1
                  На самом деле разница в методе разделения.

                  На VPS используется ядро родительской системы для работы виртуального сервера, таким образом невозможно поставить другую операционную систему или перекомпелировать ядро.

                  Под VDS создается полностью автономный виртуальный сервер на который вы можете поставить все что пожелаете хоть с диска и скомпилировать как вам надо.

                  По крайне мере так сложилось.
                  • 0
                    Ох уж эти маркетологи и сисадмины ;)
                    • +1
                      Больше маркетологи ибо если кто то поймает разницу между виртуалкой например на Xen и OpenVZ и ему разница это действительно нужна, он на название смотрит а на суть сразу=)
    • +3
      а что не так с ним? Это просто файл настройки — не более того. Или я что то не понимаю? И это не привязка продукта — это настройка окружения
      • 0
        Может у человека свой сервак под столом.
        Хотя как по мне, если мне нужны разные настройки под разные сайты, я точно не полезу в httpd.conf их переписывать, даже если у меня будет к нему доступ. Или в php.ini
      • 0
        Включение htaccess заставляет сервер при каждом запросе обшаривать каталоги от запрошенного вверх до корня сайта. Что отрицательно сказывается на производительности. Поэтому на нагруженных серверах его поддержку выключают. А сервера, изначально заточенные на производительность вообще не имеют аналогичного механизма.
        • 0
          А если htaccess положить в каждый каталог!?
          А можете какие нибудь результаты тестов производительности привести что бы было ясно о каком проценте производительности идет речь.
          • +1
            В каждый каталог или не в каждый, а пройти придётся до корня, потому что .htaccess в нижележащих каталогах переопределяют, действия .htaccess из более высоколежащих, но не отменяют их совсем.

            Наконец, добрался до тестов. Нулевой файл в каталоге с вложенностью пять от корня. ab -n10000 -c100. Q6600, 4Гб. Apache не оптимизированный, так как на домашней машине только для тестов. Gentoo, 64bit. По 4-5 тестов.

            При AllowOverride All выдаёт 8,1..8,8 тыс. запросов в секунду. С AllowOverride None — 10,8-12,3 тыс.

            Это на простаивающей машине, где кроме Apache ничего в это время не грузило. Если дисковая система будет чем-то занята, то разница может стать ещё больше.
            • 0
              Сильно…
              Стоит подумать над оптимизацией этого процесса…

              Кстати, не знаете, а если не будет htaccess Апач, будет пытаться его искать!?
              • 0
                Вот у меня в примере, как раз, .htaccess и отсутствовали. Естественно, apache должен убедиться, что этих файлов нет и просмотреть все каталоги от запрашиваемого до корня сайта.

                С работающим .htaccess должно быть ещё немного медленнее — прочитать, распарсить…
        • 0
          Ну если уж совсем-совсем строго, то апач не очень совсемстим с хайлоадом. А если мы его за легким кэширующим фронтом прячем, то такие мелочи как хтаксесс погоду не сделают.

          С другой стороны дефакто хтаксесс работает на подавляющем большинстве виртуальных хостингов и по умолчанию на всех вдс.
          • 0
            В общем, да. Apache считается достаточно тяжеловесным сервером. И хотя я его под высокой нагрузкой не практикую, люди с прямыми руками умудряются его разгонять до вполне конкурентоспособной производительности. И отключение .htaccess — это обычно первая операция в разгоне :)

            Ну а что на виртхостах включён — так это там единственный способ конфигурить свою систему простому юзеру :) Я ради этого его тоже держу, пускать в песочницу знакомых и т.п. Там не только .htaccess работает, там mpm_itk задействован, который вообще почти в 10 раз снижает скорость :)
  • +1
    Создатели HTML5 Boilerplate предлагают свой вариант идеального .htaccess, рекомендую ознакомиться.
    • 0
      Не было ещё времени капнуть этот продукт.
      Уже в закладках на ближайшие исследования, но руки ещё не дошли.

      А прямую ссыль на рекомендации по htaccess не подскажите?
      • +2
        • 0
          Спасибо.
          Очень интересно.
          Вы только что потратили пару моих часов отведенных на сон.

          Замечу, что для новичков сложноваты некоторые из приемов.
  • 0
    Это все очень хорошо и я всегда внимательно читаю такие заметки в вношу изменения в свои файлы конфигурации но есть одно НО. Заметил что размещая сайты на зарубежных хостингах (у нас такого не замечал) например на хостере 1&1 или veeble все эти настройки не работают! Сайт вечно выпадает в 500. Благо у меня уже опыт появился и 4 проекта успешно работают. Но приходится чуть не все отрубать. Прописывать специальные опции чтоб работал PHP как не странно и все такое. Никакие php_value не работают и так далее. И главное вот буквально месяца два назад сдал проект, клиент доволен, временно его домен крутится на моем домашнем сервере — начинаю переносить не работает ничего. Я клиенту обьяснил что ограничения безопастности мол пол инета жалуется на ограничения хостера — он говорит давайте я на другом куплю. Купили на veeble -ну тлже самое, просто страх.
    • 0
      Честно говоря с зарубежными хостерами мало сталкивался…
      А чем их саппорт объясняет такие действия?

      А VPS у них брать не пробовали? Все таки возможностей натыкать модулей больше становится.

      И насчет заметок и внесения изменений в файлы. Я такой… Там выше ссылоку даже на один очень интересный .htaccess почитайте. Мне очень понравилось. Куча полезностей разных.
      • 0
        ## this line is specific for 1and1 hosting
        AddType x-mapp-php5 .php
        AddHandler x-mapp-php5 .php

        Вот такое нужно прописать на 1&1, нашел в их саппорте, иначе не работает PHP, пятая версия или нет, но все просто колом встает и все.

        Сейчас сравнил разные .htaccess с разных тех сайтов, так на вскидку не скажу, но есть свои особенности что работает а что нет.

        Options -MultiViews

        Вот так на Veeble нужно дописать вместе к Options +FollowSymLinks иначе не работает mod_rewrite.
    • +1
      А вы уверенны что для работы PHP используется модуль веб-сервера apache mod_php а не режим fastCGI? Во втором случае конфигурировать php через htaccess не получиться.
      • 0
        Если я правильно понял, то речь не только о php_value… А вообще о большинстве директив и опций htaccess
        • 0
          Не знаю конечно не работал с этими хостингами, просто очень похоже, при настройках PHP FastCGI, включение директив php_value в .htaccess итог 500я ошибка, это классика.
          • 0
            Это да. Вообще конечно надо подправить пост и указать там условие <ifModule mod_php.c> чем сейчас и займусь.
  • 0
    Есть отличный способ заставить работать сайт быстрее, искать хостера где php работает в режиме fastCGI и чтобы Apache не было совсем или был на Background.

    Но тогда этот костыль с htaccess уже не будет работать.
  • 0
    … Для тех у кого всё получилось, идём на webpagetest.org мерять красоту до и после.
    Кстате, не мешало бы сказать копи-пастерам что
    <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteBase /
        RewriteCond %{HTTP_HOST} ^black-web
        RewriteRule (.*) http://www.black-web.ru/$1 [R=301,L]
        RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
        RewriteRule ^index\.php$ http://www.black-web.ru/ [R=301,L]
    </IfModule>
    

    … может не работать не так как ожидаеться во всяких самописных штуках ( я не про тех, у кого Joomla/Wordpress/Drupal/etc)
    • 0
      За ссыль, спасибо.

      А насчет самописных штук. Тут все от рук зависит. Но трудно представить, что бы человек навернул код так, что бы данные условия не работали. Этож как надо извернуться в коде, что бы это вызвало ошибки в перенаправлениях.
  • +2
    Что-то у вас по адресу www.black-web.ru/alex.roosso выдается текст скрипта, а не сама страничка.
    • 0
      Читал когда-то, что под большой нагрузкой у апача (к сожалению не помню версию и актуальность темы) бывает такая фича, что он перестает считывать хтаксесс и выполняет все по умолчанию, а иногда и вообще без того же пхп к примеру.
      Я не думаю что это именно тот случай, но я параноик и не то что расширения вот так вот не меняю, но даже у стандартных пхп делаю по старинке:
      <?php
      // Проверим что нас вызвали откуда надо, а не напрямую...
      if (!defined('dummyCONSTANT')) die('I love U baby.....');
      

      Хоть у меня и идет:

      RewriteCond %{REQUEST_FILENAME} !index\.php$
      RewriteRule ^.*\.php$ /index.php [L,QSA]
      

      ПЫСЫ: когда почините Вашу настройку по расширению подмигните плиз… Хочу еще один момент проверить…
      • +1
        Вот это:
        if (!defined('dummyCONSTANT')) die('I love U baby.....');
        никак не спасает от того, если апач решит отдать страницу как текст.
        Кстати, что-то подобное кажется случалось на фриланс.ру.
        Ну и если хочется спец-расширений для скриптов, то лучше уж тогда из прописать в конфиге апача для определенного виртуального хотса, если конечно есть доступ.
        • 0
          Не спасает, но хоть что-то… Есть решение лучше?
          В принципе есть — держать конфиг ниже корня, но это не работает для типовых решений — не каждый пользователь поймет куда это его просят залить конфиг :)
          • 0
            Почему нет, например сам конфиг можно прикрыть вот так:

            <files config.php>
            order allow,deny
            deny from all
            </files>

            Примерно также можно прикрыть доступ к остальным скриптам, кроме index.php и подобного, но оно не так нужно. Главное конфиг прикрыть.
            • 0
              Хорошая шутка, поржал, спасибо.
              Держать конфиг выше корня это хотя-бы ДОСТУПНО на любом хостинге (ну почти).
              Не понятно, но доступно. А это… в общем кроме как «поржал» других слов нет.
              • 0
                А в чем собственно заключалась моя шутка?
      • 0
        Починил…

        Кстати тоже по старинке проверяю место запуска скрипта.
    • 0
      О да… Щерт…
      Снова обновил htaccess и забыл просто строчку с указанием addhandler
      Спасибо.
  • +1
    Литература от гуру .htaccess made easy
  • 0
    Спасибо! Наконец-то статья написанная легко и ясно.
  • 0
    Вы молодец, что в примерах прописали ifModule. Новички часто ищут статьи про .htaccess, но редко кто из их (да и авторы статей не всегда) задумываются про обработку ошибок конфигурации.
    • 0
      Я даже отдельно указал об этом ниже под примером.
      Но кстати тоже заметил, что при постинге люди забывают упоминать о данном факте. (Хотя большая половина идет перепостом, поэтому кто где в самом начале накосячил не установить)
  • 0
    #кэшировать флэш и изображения на месяц

    Header set Cache-Control «max-age=2592000»

    А я вот тут картинки обновил на сервере. У пользователя они будут через месяц?
    Js на неделю? у меня 3-4 выкатки на staging в день, большая часть касается js css
    Html на день?
    Да что такое, почему? Почему вы предлагаете ограничить возможность изменения данных на уровне веб сервера?
    • 0
      Вообще было и не раз, что крупные сервисы отражают в именах статики версию файла. По крайней мере пару лет назад так работали все CDN которые не для публики а для себя… вполне себе логика, если уж так невтерпеж менять дизайн и прочее динамически.

      Что касается html, то автор разделяет php и html. По логике у него html это статика…
      Хотя согласен, об этом нюансе стоит рассказать, ибо если не анализировать то можно не заметить (я анализировал ибо ищу хорошие решения для своего фреймворка и автоматом уже вижу у кого что и как сделано даже по косвенным признакам :)
      • 0
        Кешированием должен заниматься сервер приложений. max-age — жестокий брутфорс, в моих приложениях он всегда 0.
        Я с трудом могу представить себе систему в которой контент не меняется динамически. Homepage?
        Я не считаю себя крупным серdиcом, у меня всего 10 картинок на амазоне лежит, однако пути к ним все s3-eu-west-1.amazonaws.com/foo-bar/magnify.jpg?1350015777. А браузер пусть сам запоминает видел ли он эту картинку или нет.
        Весь html динамический, кэш отдает сервер приложений, потому, как веб-сервер не может знать, изменились ли данные объекта и, соотвественно, изменилось ли содержимое представления.

        Веб серверу нельзя управлять кешированием! Однако, веб сервер должен уметь читать заголовки в которых ему четко и ясно скажут, что свежак, а что 304.
        • 0
          Сильно зависит от задачи.
          Я статику тупо отдаю по умолчанию ибо если она критична, то уж надо оптимизировать по взрослому, если не критична, то и дефолты справятся…
          Но на моей практике полно задач в которых контент относительно статичен, и необходимая динамика терпит тот же час к примеру для динамики аж бегом.
          А согласитесь динамический кэш в базе довольно мутная тема, которая требует лишний раз напрягаться — начинающий разраб этого делать не будет. Так что в простых задачах лучше ну его нафиг, и если есть возможность то отдать это на откуп вебсерверу.

          Если же мы говорим о реально серьезном проекте, то модулей может быть не много, а очень много… прописывать логику кэширования в каждом конкретном случае бывает лень, тем более что уровень разрабов на прикладных участках не всегда высок. И тут довольно неплохо показывает себя многоуровневая схема — в некритичных участках ставим кеширование по времени + 304 по ётагу… а уже перед этим механизмом кэширования стоит динамический кэш приложения, который может отдать значение задержки в ноль (я обычно все развно 1-5 сек даю), и вручную уже через свой кэш выбирать когда обновлять а когда нет…

          Итого если совсем упрощенно, то я бы сказал, что в простых задачах кеширование вебсервером полезно, и в больших тоже полезно… а в середине оно действительно неуместно :)
          • 0
            Интересно.
            В общем ваши тезисы мне понятны. Я, для себя, не принимаю следствие, т.к. повсеместно использую кеширование, везде предусматривая callbacks, когда кеш теряет актуальность, но это, как мне кажется — предмет диалога, нежели спора.
            Однако начинающие разрабы поставят max-age и будут утверждать, что google chrome кэширует method DELETE. Отсутствие лишнего напряжения может привести к многочасовому дебагу в виду того, что разработчик «скопипастил серебряную пулю и растолкал по папкам».
            Вы, возможно, возразите, что «хождение по мукам» неизбежно для разработчика, но я возражу, что, например, неделя для js — вызывает butthurt в 146% случаев, и подводить к такому спорному решению — зло.
            • 0
              Ну на счет динамического контента согласен. У меня на него по умолчанию 1сек стоит во вьюве, если не указать другое число. Что касается статики, тот тут сильно-сильно от проекта зависит. Если сделал и забыл, то почему бы и не держать неделю статику? Если же постоянно идут изменения и релиз на продакшен уходит чаще чем раз в месяц, то у заказчика явно хватит денег чтобы покрыть расходы на ресурсы для значительно более короткого периода кэширования…
              Вообще с общей тезой о том, что над временем кэша нужно думать индивидуально а не засовывать это в типовое решение я согласен… По здравому размышлению даже и не пойму никак чего я спорю то? :)
              • 0
                А не спорили мы. Я наблюдаю две адекватные точки зрения на проблему. Приятно провел время, спасибо. :)
    • 0
      Настраивайте как удобней.
      Я вам панацею предложил?
      И как написали ниже неужели трудно вставлять js таким образом:
      <link rel="stylesheet" type="text/css" href="style.css?v=1" media="screen" />
      

      или
      <link rel="stylesheet" type="text/css" href="style.css?sid=5sdf4fs...." media="screen" />
      
      • 0
        И в догонку…

        Скажем у вас баннеры jpg которые не надо кешеровать. Сложите их в отдельную папку и в неё положите .htaccess у которого кеш изображений будет минуту или 2 секунды.
        • 0
          Скажем jpg банеры нужно кешировать, поэтому fingerprint + max-age=0
      • 0
        Зачем тогда max-age?
        • 0
          Не понял вопрос. Уточните, если не трудно.
          • 0
            Если вы контролируете версию style.css, значит вы контролируете версию style.css. Т.о. max-age для style.css == 0. Потому как не веб сервер контролирует версию файла, а вы. Отсюда вытекает вопрос: зачем max-age отличный от 0.
            • 0
              Срок жизни указываем для загруженной пользователем версии.
              Обновили свой стиль. Появилась новая версия. И грузится пользователю, как новая версия, а не как старая. Но при это кешируется, до появления следующей версии или истечения срока жизни.
              • 0
                Вопрос был в том, почему не бесконечный срок жизни, если при смене все равно другой адрес будет.
                Тут такое дело… С одной стороны с нулем мы замусореваем кэш клиента, с другой стороны вечным он все равно не будет, и по какому-то принципу и так чистится, так что можно и вечным сделать если такой статики не очень-очень много, и она не меняется очень-очень часто…
                • 0
                  В принципе то верно.
                  Но зачем дожидаться, когда у человека иссякнет место под кеш или наступит время удаления по настройкам браузера.
                  У хрома вообще по-умолчанию мало места под кеш, а у Осла так почти немерено по сравнению с другими браузерами. И у осла кстати постоянно глючит автоматическая чистка кеша.

                  Я все таки наверное склонюсь к тому, что под данным углом зрения на эту проблему — это больше вопрос вежливости.
                  • 0
                    Ниадназначна… Ему мои полтора файла погоду не сделают. А вот мне стопитсот лишних запросов погоду сделать могут. Тут оно конечно 304, но вообще по разному бывает.
                    Хотя согласен, что в 99% случаев неделя или месяц будет вполне нормально
                  • 0
                    Годный вышел холивар. Я так и не могу однозначно сказать чья точка зрения в итоге верна.
                    Но в попытке номер два, по созданию идеального .htaccess, я бы уделил этим тонкостям больше внимания :)
  • 0
    оффтопик
    тут был пост не к месту...
    А как удалить пост?
    • 0
      Никак. Я вообще уверен, что тема с бесконтрольным редактированием сообщений не вечна, и что скоро сделают у отредактированных постов возможность видеть старую версию. Это больше соответствует духу Хабра :)
      • 0
        Было бы классно.
        Сразу было бы понятно, что человек имел ввиду и что написал… =) Правда все быстро привыкнуть и снова станут за собой следить.
  • 0
    как перенаправить всех, кроме посетителей из известной сети (по IP)?
    • 0
      Примерно так:

      <IfModule mod_setenvif.c>
      	SetEnvIf REMOTE_ADDR 192.168.1.1 REDIR="redir"
      </IfModule>
      <IfModule mod_rewrite.c>
      	RewriteEngine on
      	RewriteBase /
      	RewriteCond %{REDIR} redir
      	RewriteRule ^/$ /target.php
      </IfModule>
  • 0
    У меня после
    <IfModule mod_setenvif.c>
        SetEnv TZ Europe/Moscow
    </IfModule>
    

    сайт упал на 500 ошибку. По этому я юзаю такой вариант
    php_value date.timezone Europe/Moscow
    


    А кэшик настроил так:
    # Разрешение кеширования в этой папке
    # Необходимо включение модулей
    # mod_headers.c и mod_expires.c
    #
    <IfModule mod_expires.c>
    	ExpiresActive on
    	#ExpiresDefault "access plus 1 hours"
    	#ExpiresDefault "access plus 10 years"
    	ExpiresDefault                          "access plus 1 month"
    	ExpiresByType text/cache-manifest       "access plus 59 seconds"
    	ExpiresByType text/html                 "access plus 59 seconds"
    	ExpiresByType text/xml                  "access plus 59 seconds"
    	ExpiresByType application/xml           "access plus 0 seconds"
    	ExpiresByType application/json          "access plus 0 seconds"
    	ExpiresByType application/rss+xml       "access plus 1 hours"
    	ExpiresByType image/x-icon              "access plus 1 week"
    	ExpiresByType image/gif                 "access plus 1 year"
    	ExpiresByType image/png                 "access plus 1 year"
    	ExpiresByType image/jpg                 "access plus 1 year"
    	ExpiresByType image/jpeg                "access plus 1 year"
    	ExpiresByType video/ogg                 "access plus 1 year"
    	ExpiresByType audio/ogg                 "access plus 1 year"
    	ExpiresByType audio/mp3                 "access plus 1 year"
    	ExpiresByType video/mp4                 "access plus 1 year"
    	ExpiresByType video/webm                "access plus 1 year"
    	ExpiresByType text/x-component          "access plus 1 month"
    	ExpiresByType font/truetype             "access plus 1 year"
    	ExpiresByType font/opentype             "access plus 1 year"
    	ExpiresByType application/x-font-woff   "access plus 1 year"
    	ExpiresByType image/svg+xml             "access plus 1 month"
    	ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
    	ExpiresByType text/css                  "access plus 1 hours"
    	ExpiresByType application/javascript    "access plus 2 months"
    	ExpiresByType text/javascript           "access plus 2 months"
    <IfModule mod_headers.c>
    	Header append Cache-Control "public"
    </IfModule>
    </IfModule>
    
    • 0
      сайт упал на 500 ошибку. По этому я юзаю такой вариант

      Странно…

      А кэшик настроил так:

      Сугубо личное дело ;)
  • 0
    А что про это скажете — тут попытки продолжаются: github.com/h5bp/server-configs-apache

    (сюда ведет ссылка с developers.google.com)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.