Недавно я искал способ правильно определить протокол, в соответствии с которым запрос url был отправлен на сервер.
Я наблюдал через parse_url()
и, несмотря $_SERVER
суперглобальную переменную $_SERVER
, и нашел это:
<?php header('Content-Type: text/plain'); print_r($_SERVER); ?>
Вывод:
[REQUEST_SCHEME] => http
Однако я не смог найти его на php.net или Google. Хотя, я смог найти этот вопрос. Q # 1: Если $_SERVER['REQUEST_SCHEME']
не был задокументирован, то он, вероятно, ненадежен или ему можно доверять?
VC9 PHP 5.4.14 TS
использую VC9 PHP 5.4.14 TS
под окнами для разработки. Но моя продукция находится под ubuntu. Q # 2: Является ли это свойство также доступным и под Linux ubuntu?
Трудно доказать, что она надежна, но легко доказать, что она ненадежна (если бы я мог предоставить случай, который не работает). И я могу доказать, что это ненадежно, потому что оно не работает с IIS 7.0 + PHP 5.3
Переменная среды REQUEST_SCHEME
задокументирована на странице Apache mod_rewrite . Однако он не стал доступен до Apache 2.4.
У меня только Apache 2.2, поэтому я создал переменную среды. Я добавил следующее в верхнюю часть моего файла .htaccess.
RewriteEngine on # Set REQUEST_SCHEME (standard environment variable in Apache 2.4) RewriteCond %{HTTPS} off RewriteRule .* - [E=REQUEST_SCHEME:http] RewriteCond %{HTTPS} on RewriteRule .* - [E=REQUEST_SCHEME:https]
Теперь я могу использовать
%{ENV:REQUEST_SCHEME}
в других условиях и правилах перезаписи $_SERVER['REQUEST_SCHEME']
в моем PHP-коде Мне не нужно делать лишние беспорядочные условные проверки везде, и мой PHP-код является передовым. Когда Apache обновляется, я могу изменить файл .htaccess.
Я не знаю, как вы примените это к среде Windows. Это, вероятно, не очень хорошее решение для распределенного кода, но оно хорошо работает для моих нужд.
Я тоже не смог найти ссылку на REQUEST_SCHEME
, но если вы хотите определить, был ли запрос сделан http:
или https:
тогда вы можете использовать $_SERVER['HTTPS']
, который установлен на -пустое значение, если запрос был сделан https:
Это описано на сайте PHP здесь.
В новой версии Nginx устанавливается по умолчанию fastcgi_param REQUEST_SCHEME $scheme
.
Поскольку эта переменная недоступна во всех версиях сервера, безусловно, она не является надежной только для ее тестирования . Вместо этого вы можете изменить свой PHP-код, чтобы протестировать еще две переменные среды сервера, что также может указывать на то, что https используется, как показано ниже:
if ( (! empty($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] == 'https') || (! empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (! empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443') ) { $server_request_scheme = 'https'; } else { $server_request_scheme = 'http'; }
Как сказал toxalot, REQUEST_SCHEME является собственной переменной Apache с версии 2.4 (у Apache 2.2 ее нет). И, если переменная не задана сервером, PHP не будет включать ее в свой глобальный массив $ _SERVER.
К счастью, для совместимости с ошибками REQUEST_SCHEME, основанных на кодах, вы можете создать эту переменную в Apache 2.2, редактируя все файлы конфигурации хоста (httpd.conf, ssl.conf, 000-default.conf, vhosts.conf), добавляя следующие строки :
# FOR HOSTS LISTENING AT PORT 80 SetEnvIf Request_Protocol ^HTTP/ REQUEST_SCHEME=http # FOR HOSTS LISTENING AT PORT 443 SetEnvIf Request_Protocol ^HTTP/ REQUEST_SCHEME=https
Усиление предложения toxalot для пользователей CloudFlare:
RewriteEngine on RewriteCond %{HTTPS} !on [OR] RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"' RewriteRule .* - [E=REQUEST_SCHEME:http] RewriteCond %{HTTPS} on [OR] RewriteCond %{HTTP:CF-Visitor} '"scheme":"https"' RewriteRule .* - [E=REQUEST_SCHEME:https]
Это значение зависит от вашего веб-сервера. Если вы используете nginx (v1.10), в файле /etc/nginx/fastcgi_params
вы можете увидеть следующие строки:
fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty;
Как правило, это значения по умолчанию являются достаточными. Но возможно, что это не сработает, вы можете заставить эти значения в своем vhost:
include fastcgi_params; fastcgi_param REQUEST_SCHEME https; fastcgi_param HTTPS On;
Если вы используете Apache, вы можете взглянуть на сообщение пользователя toxalot