PHP Протокол URL-адреси веб-сайту - http vs 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? Таким чином ви можете перевірити це на собі.
Фрейзел Томас

Так, це було б дивним, але я не знаю, як це зробити.

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

Просто швидке запитання ... як же ти виконуєш функцію, якщо вона не динамічна. Це не так, як ви годуєте його будь-якими варами, щоб змінити URL-адресу. Чому б не визначити константу? Це я і зробив. $ Protocol = (! порожній ($ _ SERVER ['HTTPS']) && $ _SERVER ['HTTPS']! == 'off' || $ _SERVER ['SERVER_PORT'] == 443)? "https: //": "http: //"; визначити ('SITE_URL', $ протокол. $ _ SERVER ['HTTP_HOST']. '/');
HTMLGuy

Чи можу я запропонувати це? stackoverflow.com/questions/6768793/get-the-full-url-in-php
Тімо Huovinen

Відповіді:


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, головним чином, залежить від налаштування вашого веб-сервера
Іво,

Будь-яка причина, чому ви використовуєте 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)
Jesús Carrera

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']. Багато фреймворків встановлюють цю змінну як хибну або «вимкнено» і т. Д., Тому перевірка, чи вона просто встановлена, не буде працювати.
Даніель Девхерст

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

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']?


Чи можете ви додати ще трохи інформації до своєї публікації, а не лише код? Наприклад, поясніть, чому це відповідь на питання?
ndsmyter

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://
nathanfranke

Якщо сервер не підтримує https, чому б код все-таки повертався https?
CONvid19

Мій сервер підтримує https, але $_SERVER["HTTPS"]змінна ніколи не визначається.
nathanfranke

Мене бентежать ваші 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 зі своїм прізвищем.


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.