PHP определить https или http используется при подключении

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

1 thought on “PHP определить https или http используется при подключении”

  1. Вот так по моему лучше.

    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’;

Добавить комментарий

Ваш e-mail не будет опубликован.