PHP Получить протокол URL сайта - http против https


197

Я написал небольшую функцию для установления текущего протокола URL сайта, но у меня нет SSL и я не знаю, как проверить, работает ли он по протоколу https. Можете ли вы сказать мне, если это правильно?

function siteURL()
{
    $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
    $domainName = $_SERVER['HTTP_HOST'].'/';
    return $protocol.$domainName;
}
define( 'SITE_URL', siteURL() );

Нужно ли делать это, как указано выше, или я могу просто сделать это как?

function siteURL()
{
    $protocol = 'http://';
    $domainName = $_SERVER['HTTP_HOST'].'/'
    return $protocol.$domainName;
}
define( 'SITE_URL', siteURL() );

При использовании SSL сервер не преобразует автоматически URL-адрес в https, даже если URL-адрес тега привязки использует http? Нужно ли проверять протокол?

Спасибо!


1
Не лучше ли установить локальный веб-сервер и добавить на него самозаверяющий SSL-сертификат? Таким образом, вы можете проверить это сами.
Frazell Thomas

Да, это было бы здорово, но я не знаю, как это сделать.

4
Хотя это не отвечает на ваш вопрос, лучшим решением вашей проблемы (хотя я не уверен, не зная больше), может быть использование URL-адресов, относящихся к протоколу .
Риз Мур

Просто быстрый вопрос ... почему вы делаете функцию, если она не динамическая. Это не так, как вы кормите это любые переменные, чтобы изменить URL. Почему бы не определить константу? Это то, что я сделал. $ protocol = (! empty ($ _ SERVER ['HTTPS'])) && $ _SERVER ['HTTPS']! == 'off' || $ _SERVER ['SERVER_PORT'] == 443)? "https: //": "http: //"; define ('SITE_URL', $ protocol. $ _ SERVER ['HTTP_HOST']. '/');
HTMLGuy

Ответы:


69

Это не автоматически. Ваша верхняя функция выглядит хорошо.


19
Стоит отметить, что это автоматически, если вы просто отключите протокол .. т.е. //mysqite.comвместоhttps://mysitecom
я боролся с медведем один раз.

4
@Pamblam, // отлично работает, если ваша ссылка не в электронном письме :)
TimoSolo

Или в запросе xhr
Лукас Морган

86

Я знаю, что уже поздно, хотя есть гораздо более удобный способ решить эту проблему! Другие решения довольно грязные; вот как бы я это сделал:

$protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === 0 ? 'https://' : 'http://';

... или даже без условий, если вы предпочитаете:

$protocol = strtolower(substr($_SERVER["SERVER_PROTOCOL"],0,strpos( $_SERVER["SERVER_PROTOCOL"],'/'))).'://';

Посмотри на $_SERVER["SERVER_PROTOCOL"]


20
Это не работает с "https" stackoverflow.com/questions/16825243/…
wormhit

@wormhit это в основном зависит от того, как настроен ваш веб-сервер
Ivo

Любая причина, почему вы используете striposвместо strpos?
Фред

12
$_SERVER['SERVER_PROTOCOL']предназначена для хранения HTTP/1.0или в HTTP/1.1зависимости от версии протокола, о какой конфигурации HTTP-сервера вы говорите, храня httpsинформацию об этой строке, полученную из запроса http?
Regilero

1
Не работает в моем случае! $ _SERVER ['SERVER_PROTOCOL'] содержит «HTTP» (без «S»), а протокол - https. Проверка $ _SERVER ['HTTPS'] более уместна.
Саймон Привет

68

Это работает для меня

if (isset($_SERVER['HTTPS']) &&
    ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) ||
    isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
    $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
  $protocol = 'https://';
}
else {
  $protocol = 'http://';
}

3
Это решение, которое работает при использовании прокси (как в моем случае CloudFlare)
Хесус Каррера

1
Это правильно - вы не должны принимать https только потому, что используете порт 443.
Марк Фишер

24

Некоторые изменения:

function siteURL() {
  $protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || 
    $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
  $domainName = $_SERVER['HTTP_HOST'];
  return $protocol.$domainName;
}


7

По моему мнению, тестирование номера порта не является хорошей практикой:

define('HTTPS', isset($_SERVER['HTTPS']) && filter_var($_SERVER['HTTPS'], FILTER_VALIDATE_BOOLEAN));

В HTTPSпостоянной отдачи , TRUEесли $_SERVER['HTTPS']установлен и равен «1», «правда», «на» или «да». В противном случае возвращает FALSE.


Это, наверное, лучший ответ. Многие из этих ответов будут только в процентах ситуаций. Например, люди просто проверяют, установлен ли $ _SERVER ['HTTPS']. Многие платформы устанавливают эту переменную как false или «off» и т. Д., Поэтому проверка, установлена ​​ли она просто, не будет работать.
Дэниел Дьюхерст

1
Хотя это работает в большинстве ситуаций, были времена, когда была конфигурация SNAFU, и $ _SERVER ['HTTPS'] фактически было установлено на «off». Ваш код все равно будет расценивать это как «прохождение» теста, поэтому его следует изменить, чтобы учесть этот конкретный параметр.
Дейв Мортон

6

Для любой системы, кроме IIS, этого вполне достаточно для определения собственного URL сайта:

$siteURL='http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['HTTP_HOST'].'/';

или

$siteURL='http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'].'/';

зависит от того, что именно вы хотите: HTTP_HOST или SERVER_NAME


5

В случае прокси SERVER_PORTможет не дать правильное значение, так что это то, что сработало для меня -

$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443 || $_SERVER['HTTP_X_FORWARDED_PORT'] == 443) ? "https://" : "http://"

4

Используйте эту переменную сервера, чтобы получить подробности протокола:

 $scheme = $_SERVER['REQUEST_SCHEME'] . '://';
 echo $scheme; //it gives http:// or https://

Обратите внимание, что эта переменная сервера ненадежна. Для получения дополнительной информации взгляните на: Является ли $ _SERVER ['REQUEST_SCHEME'] надежным?


Можете ли вы добавить больше информации в свой пост, а не только код? Например, объясните, почему это ответ на вопрос?
ndmyter

3

Я знаю, что это старый вопрос, но я столкнулся с этим сегодня, так как мне нужно было проверить это на моем сайте. Кажется, ответы выше неоправданно сложны. Чтобы установить протокол сайта, все, что вам нужно сделать, это проверить$_SERVER['HTTPS']

Если протокол использует HTTPS, то $_SERVER['HTTPS']вернется «вкл». Если нет, переменная останется пустой. Например:
// test if HTTPS is being used. If it is, the echo will return '$SSL_test: on'. If not HTTPS, '$SSL_test' will remain empty.

$SSL_test = $_SERVER['HTTPS'];

echo '<p>$SSL_test: '.$SSL_test.'</p>';

if($SSL_test == true) {
    echo 'You\'re using SSL';
} else {
    echo 'You\'re not using SSL';
} 

Вы можете использовать вышеупомянутое, чтобы легко и точно протестировать HTTPS и реализовать соответственно. :)


2
Не каждый сервер имеет этот $ _SERVER ['HTTPS']
ChrisDeDavidMindflowAU

2

сделал функцию, используя ответ Rid Iculous , который работал на моей системе.

function site_protocol() {
    if(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&  $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')  return $protocol = 'https://'; else return $protocol = 'http://';
}

Надеюсь, поможет


2

Я проверил ответ, получивший наибольшее количество голосов, и это не сработало для меня , в итоге я использовал:

$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';

Некоторые веб-серверы не поддерживают, $_SERVER["HTTPS"]и поэтому ваш код может вернуться, http://даже если он должен бытьhttps://
Натанфранке

Если сервер не поддерживает https, почему код все еще возвращается https?
CONvid19

Мой сервер поддерживает https, но $_SERVER["HTTPS"]переменная никогда не определяется.
Натанфранке

Я смущен вашими 2 комментариями. Вероятно, будет лучше, если вы создадите новый ответ, который охватывает эти особые случаи. Спасибо и удачи!
CONvid19


2

Извлечено из CodeIgniter:

if ( ! function_exists('is_https'))
{
    /**
     * Is HTTPS?
     *
     * Determines if the application is accessed via an encrypted
     * (HTTPS) connection.
     *
     * @return  bool
     */
    function is_https()
    {
        if ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')
        {
            return TRUE;
        }
        elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https')
        {
            return TRUE;
        }
        elseif ( ! empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off')
        {
            return TRUE;
        }

        return FALSE;
    }
}

0

это лучшее решение https или http использовать это:

<?php
$protocol = '//';  
$site_url = $protocol.$_SERVER["HTTP_HOST"];
?>

Но не может отображать https или http, поэтому он используется только для ссылки на контент вашего сайта, например, изображение и т. Д.

если вы хотите перенаправить ваш сайт в https, добавьте этот код в файл .htaccess:

<IfModule mod_rewrite.c>
 RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"'
 RewriteRule ^(.*)$ https://www.your-domain.com$1 [L]
</IfModule>

Измените www.your-domain.com своим именем dowmain.


0

Вот как я это делаю ... это сокращенная if else версия ответа Рида Айкула ...

$protocol = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ? 'https' : 'http';

0

Я думаю, что полная функция должна выглядеть так:

function siteURL()
{
    $protocol =  "http://";
    if (
        //straight
        isset($_SERVER['HTTPS']) && in_array($_SERVER['HTTPS'], ['on', 1])
        ||
        //proxy forwarding
        isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'
    ) {
        $protocol = 'https://';
    }

    $domainName = $_SERVER['HTTP_HOST'];
    return $protocol . $domainName;
}

Ноты:

  • Вы также должны искать HTTP_X_FORWARDED_PROTO (например, если прокси-сервер)
  • полагаться на порт 443 небезопасно (https может обслуживаться на другом порту)
  • REQUEST_SCHEME не надежно

0

Я знаю, что немного опоздал на эту вечеринку, но если вы предпочитаете не использовать $ _SERVER, так как он сильно не рекомендуется и даже деактивируется в некоторых PHP-фреймворках; и у вас есть веб-сервер Apache, вы можете использовать его собственную команду таким образом: -

$protocol = apache_getenv('HTTPS') ? 'https:' : 'http:';
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.