Заголовок вышел немного корявый, но суть следующая — как на PHP определить по какому протоколу http или https выполняется текущее подключение к сайту. Это необходимо для тех скриптов, которые используют в своей работе тег <base>, тогда все относительные ссылки будут подключатся по нужным протоколам.
Хотя в документации указано что можно проверять $_SERVER[‘HTTPS’] — все оказалось немного сложнее.
Вот полный сниппет, который у меня получился (точнее сниппет не совсем мой — когда я уже написал свой аналогичный, я нашел немного более красивый у разработчиков OkayCMS) и чуть ниже я расскажу почему именно так.
// Протокол $protocol = strtolower(substr($_SERVER["SERVER_PROTOCOL"],0,5))=='https'? 'https' : 'http'; if($_SERVER["SERVER_PORT"] == 443) $protocol = 'https'; elseif (isset($_SERVER['HTTPS']) && (($_SERVER['HTTPS'] == 'on') || ($_SERVER['HTTPS'] == '1'))) $protocol = 'https'; elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || !empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') $protocol = 'https';
Вся проблема с корректным определением протокола в кеширующих прокси, (если использовать нативный Апач, то проблем обычно нету) в зависимости от конфигов в переменных может твориться все что угодно,
В первой строке определяется протокол $_SERVER[«SERVER_PROTOCOL»] , эта строка заполнена всегда, но в зависимости от конфига сервера там может быть http даже если подключение выполняется по https (да, бывает и такое), поэтому начальное значение берется оттуда.
Далее проверяем порт, если это 443, то это точно https.
Далее если порт не такой, но в конфиге сервера указана переменная $_SERVER[‘HTTPS’], то будем надеяться что он таки не соврал и это таки https (тут есть один ньюанс, которого в сниппете нету для такого экзотического конфига как ISAPI + IIS, значение $_SERVER[‘HTTPS’] будет равно ‘off’, в случае обычного подключения, а что будет в случае https — я не знаю, т.к. проверить это не могу, просто учтите)
Ну и вишенка на тортике, это предпоследняя строка, если используются reverse proxy аля Cloudflare или хитро настроенный nginx, то все предыдущие строки будут бодро рапортовать о 80 порте и обычном подключении, а оказывается на самом деле все идет по защищенному протоколу, ибо $_SERVER[‘HTTP_X_FORWARDED_PROTO’] == ‘https’.
На это все, как видите определить http или https на php, не особо сложно, главное учесть все детали.
Вот так по моему лучше.
if($_SERVER[«SERVER_PORT»] == 443)
$protocol = ‘https’;
elseif (isset($_SERVER[‘HTTPS’]) && (($_SERVER[‘HTTPS’] == ‘on’) || ($_SERVER[‘HTTPS’] == ‘1’)))
$protocol = ‘https’;
elseif (!empty($_SERVER[‘HTTP_X_FORWARDED_PROTO’]) && $_SERVER[‘HTTP_X_FORWARDED_PROTO’] == ‘https’ || !empty($_SERVER[‘HTTP_X_FORWARDED_SSL’]) && $_SERVER[‘HTTP_X_FORWARDED_SSL’] == ‘on’)
$protocol = ‘https’;
elseif (strtolower(substr($_SERVER[«SERVER_PROTOCOL»],0,5)) == ‘https’)
$protocol = ‘https’;
else
$protocol = ‘http’;