PHP - редирект с https на http и с www на без www
**РЕДАКТИРОВАНИЕ: В итоге я разобрался. Прокрутите вниз до моего собственного ответа (отмечен зеленой галочкой)**
Сейчас я использую functions.php для перенаправления URL с https на http для сайта, у которого пока нет SSL-сертификата:
function shapeSpace_check_https() {
// Проверяем, используется ли HTTPS или порт 443
if ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443) {
return true;
}
return false;
}
function bhww_ssl_template_redirect() {
// Если используется HTTPS
if (shapeSpace_check_https()) {
if (0 === strpos($_SERVER['REQUEST_URI'], 'http')) {
// Перенаправляем с HTTPS на HTTP
wp_redirect(preg_replace('|^https://|', 'http://', $_SERVER['REQUEST_URI']), 301);
exit();
} else {
wp_redirect('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 301);
exit();
}
}
}
add_action('template_redirect', 'bhww_ssl_template_redirect');
В этой же функции я хотел бы добавить перенаправление с поддомена www на адрес без www. Я нашел хорошую функцию здесь, но мне нужна помощь с её интеграцией в мою текущую функцию. Я бы хотел избежать реализации этого в .htaccess, но буду рад и такому решению.
Как перенаправить HTTPS на HTTP и www на non-www URL с помощью .htaccess:
Сначала убедитесь, что
HTTPSработает и действителен. Это легко (и бесплатно) сделать с помощью Let's Encrypt в наше время.Примечание: Хотя вы перенаправляете
HTTPSнаHTTP, я рекомендую делать наоборот, т.е.HTTPнаHTTPS. Лучше для безопасности, SEO и совместимости с браузерами — популярные браузеры всё чаще усложняют работу сайтам наHTTP.Затем убедитесь, что
.htaccessи модульmod_rewriteработают.Затем используйте следующий КОД в файле
.htaccessвашего корневого веб-каталога (если вы уже используете там какие-либо правила, адаптируйте их соответственно с этими новыми правилами):<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTPS} =on [OR] RewriteCond %{HTTP_HOST} !^example\.com$ RewriteRule ^(.*)$ "http://example.com/$1" [R=301,L] # оставшийся htaccess mod_rewrite КОД для WordPress </IfModule>Примечание: Замените
example.comна ваше собственное доменное имя.
Почему решение с .htaccess лучше:
Лучше делать такие перенаправления на уровне веб-сервера. Из вашего вопроса, поскольку ваш веб-сервер, похоже, Apache, лучше сделать это через .htaccess. Почему:
- Это быстрее.
- Ваш файл
functions.phpостаётся чище и делает то, для чего он изначально предназначен, т.е. модификации темы. - Смена темы не повлияет на это.
- Для каждого перенаправления не нужно загружать всю кодовую базу WordPress дважды — один раз до перенаправления и затем после перенаправления.
Спасибо за это. Я попробовал, но почему-то изменения в .htaccess не вступают в силу (я пробовал ваш способ и другие). Интересно, нужно ли мне что-то перезапустить, чтобы заставить это работать.
Kyle Vassella
Прежде всего, если вы не установите HTTPS (SSL) должным образом, то правила .htaccess для HTTPS могут вообще не работать (я уже писал об этом в своем ответе). Также вы должны убедиться, что .htaccess действительно работает на вашем сайте, потому что если это так, перезапуск не должен требоваться.
Fayaz
Взят из вашего кода, я бы рефакторил его следующим образом:
function bhww_ssl_template_redirect() {
$redirect_url='';
if ( shapeSpace_check_https() ) {
if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) {
$url = $_SERVER['REQUEST_URI'];
$not_allowed = array('https://www', 'https://');
foreach($not_allowed as $types) {
if(strpos($url, $types) === 0) {
$redirect_url = str_replace($types, 'http://', $url);
}
}
} else {
$redirect_url ='http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
$redirect_url = !empty($redirect_url)?$redirect_url:$url;
wp_redirect($redirect_url, 301 );
exit();
}
}
Добавьте правила в .htaccess для редиректа www -> non-www
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.yourdomain.com [NC]
RewriteRule ^(.*)$ http://yourdomain.com/$1 [L,R=301]
Редирект https -> http
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI}
Но опять же, для работы этого требуется наличие валидного SSL-сертификата, иначе пользователям будет показан "Экран ужаса".
Большое спасибо, что нашли время помочь. К сожалению, www не удаляется из адресной строки в моем случае - похоже, перенаправление не работает. Я исправил опечатку с лишней 'w' в 'https://wwww' в вашем коде, а также попробовал вариант с if(strpos($url, $types) !==0) вместо вашего ===0, так как подумал, что в этом может быть проблема, но ничего не вышло. Буду продолжать разбираться, что можно изменить. Если у вас есть идеи, пожалуйста, дайте знать.
Kyle Vassella
Возможно, это связано с настройками системы в файле .htaccess. Попробуйте проверить в приватном окне и поищите скрытые перенаправления.
Drupalizeme
Спасибо, что вернулись к этому вопросу. Я пробовал разные методы в .htaccess, включая ваш, но изменения не применяются - думаю, может потребоваться деактивировать и снова активировать тему WordPress, чтобы изменения в .htaccess вступили в силу, но я пока не готов на этот шаг (никогда этого не делал). Поэтому продолжу работать с PHP - пока ничего не получается. Ваш способ успешно перенаправляет с https на http, но мне все еще не удается убрать поддомен www.
Я проверил в приватном окне и не увидел скрытых перенаправлений во вкладке Network (если это правильный способ проверки) - только ожидаемый редирект с https на http с кодом 301.
Kyle Vassella
Я заметил, что после вашего оператора if else вы использовали сокращенную форму if: $redirect_url = !empty($redirect_url)?$redirect_url:$url;, но $url не определен глобально здесь - он определен только в операторе if. Не уверен, является ли это причиной или нет - возможно, $url определен глобально в PHP, или он не нужен в любом случае?
Kyle Vassella
@KyleVassella 1) Переменная $url не должна объявляться глобально, так как она служит только для локальной области видимости оператора if. Она содержит $_SERVER['REQUEST_URI'] и должна учитываться, если $redirect_url остается пустой. 2) Файл .htaccess должен работать как есть, без активации/деактивации тем. Но есть большое "если": это может измениться, если есть кэширование или что-то еще, что мешает работе правил. Я бы попробовал поместить правила в начало файла .htaccess.
Drupalizeme
Спасибо всем за помощь. Но следующий код — это то, что в итоге сработало для меня, чтобы сделать 301 редирект с https на http и с www на без www. Я разместил следующий блок кода внутри functions.php:
//проверяем, используется ли https, независимо от сертификата
function shapeSpace_check_https() {
if ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443) {
return true;
}
return false;
}
for ($x=0; $x<1; $x++) {
//если https:// && www.
if ( shapeSpace_check_https() && substr($_SERVER['HTTP_HOST'], 0, 4) === 'www.'){
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://' . substr($_SERVER['HTTP_HOST'], 4).$_SERVER['REQUEST_URI']);
exit;
break;
//если только www.
} elseif (substr($_SERVER['HTTP_HOST'], 0, 4) === 'www.') {
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://' . substr($_SERVER['HTTP_HOST'], 4).$_SERVER['REQUEST_URI']);
exit;
break;
//если только https://
} elseif ( shapeSpace_check_https() ) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
exit;
break;
}
}
Не думаю, что мне нужны break;, но точно нужны exit;, и я оставил break; на всякий случай. Пожалуйста, объясните, почему мне, возможно, не нужны оба. Приведённый выше код приводит к следующим редиректам:
https://www.example.com на http://example.com
Вот обновленная функция для перенаправления с www на без www:
function bhww_ssl_template_redirect() {
$redirect_url='';
$url = $_SERVER['REQUEST_URI'];
if ( shapeSpace_check_https() ) {
if ( 0 === strpos( $url, 'http' ) ) {
if(strpos($url, 'https://') === 0) {
$redirect_url = str_replace('https://', 'http://', $url);
}
}
elseif ( TRUE == strpos( $url, 'www.') ) {
$redirect_url = str_replace('www.', '', $url);
}
else {
$redirect_url ='http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
$redirect_url = !empty($redirect_url)?$redirect_url:$url;
wp_redirect($redirect_url, 301 );
exit();
}
}
Дайте знать, если это поможет.
Спасибо, что уделили время. Я не пробовал ваш способ, так как уже сделал свою рабочую версию. Я бы попробовал, но в тот момент не мог рисковать снова сломать работающий сайт. Ваш способ может работать, хотя навскидку мне кажется, что он не будет перенаправлять http://www.example.com на http://example.com, поскольку вся логика находится внутри if (shapeSpace_check_https() ), который, как я понимаю, проверяет использование https. Хотя я могу ошибаться.
Kyle Vassella