WordPress как на ладони
wordpress jino

Полезный хак для WordPress, если сайт дорабатывается на локалке

Начну с того, что этот пост, по сути, не несет какой-либо практической пользы для сайтов уже "установленных" на сервер и полностью готовых. Обо всем по порядку.

Делая как-то «один сайт» я скопировал его на локалку, скопировал все кроме медиафайлов, а на сайте было много картинок: минимум две к записи плюс галереи. Получалось, что ни страница, то минимум 2-3 картинки. Для того, чтобы работать над сайтом картинки мне не нужны, поэтому их я с сервера не заливал, так как трафик у меня ограниченный sad и получалось, что когда работаю на локалке на каждой странице минимум 2 битые ссылки на картинки, а то и 20.

Я заметил, что чем больше картинок на странице, тем дольше грузится страница, вплоть до 10 секунд. Меня это стало раздражать, и я начал искать причину такого ненормального поведения. Причина оказалась в том, что каждая битая ссылка на картинку "скрыто" генерировала еще одну страницу - 404. В качестве примера можете попробовать вписать ссылку типа: http://домен/kartinka.jpg и вы получите страницу с ошибкой, страницу со всем содержимым сайта, с сайдбаром(и) и прочим...

Суть дела

Получается, чтобы сгенерировать страницу с одной битой ссылкой на файл, WordPress генерирует две страницы: саму страницу и страницу с ошибкой 404. Если на странице 2 битые ссылки, то будут созданы 3 страницы и т.д.

Конечно, на рабочем сайте битых ссылок обычно нет или почти нет (см. конец поста), поэтому и проблемы такой нет, но на локалке не грузить страницу 404, если это файл очень может пригодится. Точнее, совсем не загружать не получится, но сделать ее крайне легкой не сложно.

Я решил эту проблему написав код. Его нужно вставить в самое начало в файл index.php в корневой директории сайта.

// Проверка на тип ошибки 404, если это файл не генерировать страницу,
// а просто писать об ошибке
$URIreq = $_SERVER['REQUEST_URI'];
if ( preg_match('/.(jpg|jpeg|gif|png|zip)/', $URIreq ) ){
	$PathToFileFromRoot = $_SERVER['DOCUMENT_ROOT'].$URIreq;
	$PathToFileFromRoot = str_replace( '//', '/', $PathToFileFromRoot );
	if ( !file_exists($PathToFileFromRoot) ){
		echo "<div style='margin:100px 10% 0 10%; padding:20px; text-align:center; border:1px solid #42A6FF; background:#DEF0FF; white-space:nowrap;'>
		<b>File not found:</b> $URIreq<br>
		<b>From Page:</b> <a href='{$_SERVER["HTTP_REFERER"]}'>{$_SERVER["HTTP_REFERER"]}</a><br>
		<div style='font-size:25px; padding-top:30px;'>Go to WebSite: <a href='http://{$_SERVER['HTTP_HOST']}'>http://{$_SERVER['HTTP_HOST']}</a></div>
		</div>";
		exit();
	}
}

Что делает код?

Как только запрашивается страница содержащая в ссылке .jpg, .jpeg, .gif, .png, .zip, т.е. как только запрашивается файл, он проверяется на существование, если файл не существует, то выводится заглушка и до WordPress'a дело вообще не доходит. Такая заглушка генерируется за доли секунды, что и требовалось.

Чтобы убедится, что все работает пишем в браузер http://домен/kartinka.jpg

Знатоки скажут, что 404 можно задать через .htaccess и будут абсолютно правы, но стандартный способ ErrorDocument 404 /404.html для Вордпресс не подходит, т.к. при использовании ЧПУ, используется mod_rewrite и 404-я страница определяется уже самим Вордпрессом.

Тоже самое через .htaccess

Через .htaccess сделать можно, но я не знаю как, если есть просвещенные в этом вопросе поделитесь знаниями в комментариях пожалуйста.

Поделились:

<IfModule mod_rewrite.c>

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} \.(php|s?html?|css|js|jpe?g|png|gif|ico|txt|pdf)(/?\?.*)?$
RewriteRule . - [R=404,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

</IfModule>

Внимание, для уже рабочих сайтов!

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

Для примера возьмем вот этот сайт: wordpressinside.ru, который возможно вам известен, здесь, на вскидку, я нашел как минимум 2 битые ссылки, вот они (были до написания этой статьи smile ):

  1. http://wordpressinside.ru/wp-content/plugins/simple-counters/js/sc.js.php
  2. http://wordpressinside.ru/wp-content/plugins/simple-counters/js/jquery.qtip.js
    Эти ссылки вшиты в шаблон и при генерации любой страницы, параллельно генерируется 2 страницы 404. Думаю не сложно представить насколько дольше генерируется страница, о лишних, абсолютно ненужных нагрузках на сервер я уже и не говорю...

Для решения проблемы, можно просто удалить битые ссылки - они просто не нужны...

Полезный хак для WordPress, если сайт дорабатывается на локалке 22 комментария
Полезные 1 Все
  • Не знаю, насколько эффективен данный код, но мне удалось решить проблему, озвученную в статье. Вот что должно быть прописано в .htaccess:

    <IfModule mod_rewrite.c>
    
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} \.(php|s?html?|css|js|jpe?g|png|gif|ico|txt|pdf)$ [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteCond %{REQUEST_FILENAME} !/wp-admin/$
    RewriteRule . /404.html [L]
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    
    </IfModule>

    Коротко о том, что содержится во втором блоке объявлений mod_rewrite:

    RewriteCond %{REQUEST_FILENAME} !-f

    • проверяет, чтобы файл, на который пришел запрос, отсутствовал на сервере.

    RewriteCond %{REQUEST_URI} .(php|s?html?|css|js|jpe?g|png|gif|ico|txt|pdf)$

    • ищет в строке запроса перечисленные форматы файлов.

    В принципе, этого будет достаточно, но я решил отдавать еще 404 страницу на прямые запросы ко всем каталогам, которые есть на моем сайте. Думаю, это хорошая альтернатива Options All -Indexes, которая будет возвращать ошибку 403 доступ запрещен. Поэтому для комбинирования правил после второго условия добавляем еще [OR], что значит ИЛИ.

    RewriteCond %{REQUEST_FILENAME} -d

    • проверяет, чтобы запрос указывал на каталог.

    RewriteCond %{REQUEST_FILENAME} !/wp-admin/$

    • это правило необходимо, чтобы мы не заблочили самих себя. Иначе в админку нас больше не пустит, даже если и будем авторизованы.

    RewriteRule . /404.html [L]

    • финальное правило, здесь все довольно очевидно. Указываем путь к нашему собственному файлу страницы ошибки, который в итоге будет отдаваться пользователю при соблюдении вышеописанных правил. Флаг [L] в конце обязателен.

    -

    Я пробовал использовать правило [R=404,L] вместо /404.html [L], а в начале файла прописывать ErrorDocument 404 /404.html, но увы, такой способ не прокатил - WordPress перехватывает редирект.

    1
    • Kama4639

      Спасибо за решение, добавил в статью со ссылкой на комменатрий! thank_you

      • Разобрался, почему wordpress перехватывает редирект. Необходимо перед [R=404,L] поставить прочерк и тогда все будет корректно работать. Итоговый код следующий:

        ErrorDocument 404 /404.php
        
        <IfModule mod_rewrite.c>
        
        RewriteEngine On
        RewriteBase /
        RewriteRule ^index\.php$ - [L]
        
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_URI} \.(php|s?html?|css|js|jpe?g|png|gif|ico|txt|pdf)$
        RewriteRule . - [R=404,L]
        
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.php [L]
        
        </IfModule>
        1

Здравствуйте, !

Ваш комментарий