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? Нужно ли проверять протокол?

Спасибо!

BalusC
источник
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
Могу ли я предложить это? stackoverflow.com/questions/6768793/get-the-full-url-in-php
Тимо Хуовинен

Ответы:

69

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

profitphp
источник
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;
}
Anoop K
источник
16

короткий путь

$scheme = $_SERVER['REQUEST_SCHEME'] . '://';
softcod.com
источник
3
REQUEST_SCHEMEне надежен
Фарнабаз
5
REQUEST_SCHEME не доступен до Apache 2.4.
KenB
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://"
Harshit
источник
4

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

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

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

shashik493
источник
Можете ли вы добавить больше информации в свой пост, а не только код? Например, объясните, почему это ответ на вопрос?
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://';
}

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

miyuru
источник
2

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

$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
CONvid19
источник
Некоторые веб-серверы не поддерживают, $_SERVER["HTTPS"]и поэтому ваш код может вернуться, http://даже если он должен бытьhttps://
Натанфранке
Если сервер не поддерживает https, почему код все еще возвращается https?
CONvid19
Мой сервер поддерживает https, но $_SERVER["HTTPS"]переменная никогда не определяется.
Натанфранке
Я смущен вашими 2 комментариями. Вероятно, будет лучше, если вы создадите новый ответ, который охватывает эти особые случаи. Спасибо и удачи!
CONvid19
2
$protocal = 'http';
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || $_SERVER['HTTPS'] == 'on') {$protocal = 'https';}


echo $protocal;
Саурабх Чандра Патель
источник
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 не надежно
koalaok
источник
0

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

$protocol = apache_getenv('HTTPS') ? 'https:' : 'http:';
Джонатан
источник