Является ли $ _SERVER надежным?

Недавно я искал способ правильно определить протокол, в соответствии с которым запрос 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