Ответ 1
Трудно доказать, что он надежен, но легко доказать, что он ненадежный (если бы я мог предоставить случай, который он не работает). И я могу доказать, что он ненадежен, потому что он не работает с IIS 7.0 + PHP 5.3
Недавно я искал способ правильно определить протокол, в соответствии с которым запрос url был отправлен на сервер.
Я просмотрел parse_url()
и хотя $_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
под окнами для разработки. Но моя продукция находится под 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-код является совместимым с Outlook. Когда 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
Усиление предложения токсикола для пользователей 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".