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
не вступают в силу (я пробовал ваш способ и другие). Интересно, нужно ли мне что-то перезапустить, чтобы заставить это работать.

Прежде всего, если вы не установите HTTPS (SSL) должным образом, то правила .htaccess
для HTTPS могут вообще не работать (я уже писал об этом в своем ответе). Также вы должны убедиться, что .htaccess
действительно работает на вашем сайте, потому что если это так, перезапуск не должен требоваться.

Взят из вашего кода, я бы рефакторил его следующим образом:
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
, так как подумал, что в этом может быть проблема, но ничего не вышло. Буду продолжать разбираться, что можно изменить. Если у вас есть идеи, пожалуйста, дайте знать.

Возможно, это связано с настройками системы в файле .htaccess. Попробуйте проверить в приватном окне и поищите скрытые перенаправления.

Спасибо, что вернулись к этому вопросу. Я пробовал разные методы в .htaccess
, включая ваш, но изменения не применяются - думаю, может потребоваться деактивировать и снова активировать тему WordPress, чтобы изменения в .htaccess
вступили в силу, но я пока не готов на этот шаг (никогда этого не делал). Поэтому продолжу работать с PHP - пока ничего не получается. Ваш способ успешно перенаправляет с https на http, но мне все еще не удается убрать поддомен www.
Я проверил в приватном окне и не увидел скрытых перенаправлений во вкладке Network
(если это правильный способ проверки) - только ожидаемый редирект с https на http с кодом 301.

Я заметил, что после вашего оператора if else
вы использовали сокращенную форму if
: $redirect_url = !empty($redirect_url)?$redirect_url:$url;
, но $url
не определен глобально здесь - он определен только в операторе if
. Не уверен, является ли это причиной или нет - возможно, $url
определен глобально в PHP, или он не нужен в любом случае?

@KyleVassella 1) Переменная $url не должна объявляться глобально, так как она служит только для локальной области видимости оператора if. Она содержит $_SERVER['REQUEST_URI']
и должна учитываться, если $redirect_url
остается пустой. 2) Файл .htaccess должен работать как есть, без активации/деактивации тем. Но есть большое "если": это может измениться, если есть кэширование или что-то еще, что мешает работе правил. Я бы попробовал поместить правила в начало файла .htaccess
.

Спасибо всем за помощь. Но следующий код — это то, что в итоге сработало для меня, чтобы сделать 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
. Хотя я могу ошибаться.
