PHP Uzyskaj protokół URL witryny - http vs https

197

Napisałem małą funkcję do ustanowienia bieżącego protokołu adresu URL witryny, ale nie mam protokołu SSL i nie wiem, jak sprawdzić, czy działa on pod https. Czy możesz mi powiedzieć, czy to prawda?

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() );

Czy trzeba to zrobić jak wyżej, czy mogę to po prostu zrobić ?:

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

W trybie SSL serwer nie konwertuje automatycznie adresu URL na https, nawet jeśli adres URL tagu kotwicy używa http? Czy konieczne jest sprawdzenie protokołu?

Dziękuję Ci!

BalusC
źródło
1
Czy nie byłoby lepszym rozwiązaniem dla ciebie, aby zainstalować lokalny serwer WWW i rzucić na niego certyfikat SSL z podpisem własnym? W ten sposób możesz sam to przetestować.
Frazell Thomas
Tak, byłoby świetnie, ale nie wiem jak to zrobić.
4
Chociaż to nie odpowiada na twoje pytanie, lepszym rozwiązaniem twojego problemu (choć nie jestem pewien, nie wiedząc więcej) może być użycie względnych adresów URL protokołu .
Reese Moore,
Krótkie pytanie ... dlaczego wykonujesz funkcję, jeśli nie jest dynamiczna. To nie jest tak, że karmisz go dowolnymi zmiennymi, aby zmienić adres URL. Dlaczego nie zdefiniować stałej? To jest to co zrobiłem. $ Protocol = (! empty ($ _ SERVER ['HTTPS']) && $ _SERVER ['HTTPS']! == 'off' || $ _SERVER ['SERVER_PORT'] == 443)? „https: //”: „http: //”; zdefiniuj ('SITE_URL', $ protokół. $ _ SERVER ['HTTP_HOST']. '/');
HTMLGuy
Czy mogę to zasugerować? stackoverflow.com/questions/6768793/get-the-full-url-in-php
Timo Huovinen

Odpowiedzi:

69

To nie jest automatyczne. Twoja najlepsza funkcja wygląda dobrze.

profitphp
źródło
19
warto zauważyć, że jest on automatyczny, jeśli po prostu zrezygnujesz z protokołu ... tj. //mysqite.comzamiasthttps://mysitecom
raz walczyłem z niedźwiedziem.
4
@Pamblam, // działa świetnie, chyba że twój link znajduje się w e-mailu :)
TimoSolo
Lub na życzenie xhr
Lucas Morgan
86

Wiem, że jest późno, chociaż istnieje znacznie wygodniejszy sposób rozwiązania tego rodzaju problemu! Inne rozwiązania są dość nieuporządkowane; tak bym to zrobił:

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

... lub nawet bez warunku, jeśli wolisz:

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

Spójrz na $_SERVER["SERVER_PROTOCOL"]

Ivo
źródło
20
To nie działa z „https” stackoverflow.com/questions/16825243/…
wormhit
@ Wormhit zależy to jednak głównie od konfiguracji serwera
Ivo
Masz powód, dla którego używasz striposzamiast strpos?
Fred
12
$_SERVER['SERVER_PROTOCOL']jest przeznaczony do przechowywania HTTP/1.0lub, w HTTP/1.1zależności od wersji protokołu, o jakiej konfiguracji serwera HTTP mówisz, przechowując httpsinformacje o tym ciągu pochodzącym z zapytania http?
regilero
1
W moim przypadku nie działa! $ _SERVER ['SERVER_PROTOCOL'] zawiera „HTTP” (bez „S”), podczas gdy protokół to https. Sprawdzanie $ _SERVER ['HTTPS'] jest bardziej odpowiednie.
Simon Hi
68

To działa dla mnie

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://';
}
Śmieszny
źródło
3
Jest to rozwiązanie, które działa, jeśli używasz proxy (jak w moim przypadku CloudFlare)
Jesús Carrera
1
To prawda - nie powinieneś zakładać https tylko dlatego, że używasz portu 443.
Mark Fisher
24

Trochę zmian:

function siteURL() {
  $protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || 
    $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
  $domainName = $_SERVER['HTTP_HOST'];
  return $protocol.$domainName;
}
Anoop K.
źródło
16

krótka droga

$scheme = $_SERVER['REQUEST_SCHEME'] . '://';
softcod.com
źródło
3
REQUEST_SCHEMEnie jest wiarygodny
Farnabaz
5
REQUEST_SCHEME jest niedostępny do Apache 2.4.
KenB
7

Ponieważ testowanie numeru portu nie jest według mnie dobrą praktyką, moim rozwiązaniem jest:

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

Te HTTPSciągłe powroty TRUEjeśli $_SERVER['HTTPS']jest ustawiony i jest równy „1”, „prawda”, „on” lub „tak”. W przeciwnym razie zwraca FALSE.

alex
źródło
To prawdopodobnie najlepsza odpowiedź. Wiele z tych odpowiedzi będzie tylko w niektórych sytuacjach. Na przykład ludzie sprawdzają tylko, czy ustawiono $ _SERVER ['HTTPS']. Wiele frameworków ustawia tę zmienną na false lub „off” itd., Dlatego sprawdzanie, czy jest ona po prostu ustawiona, nie będzie działać.
Daniel Dewhurst
1
Chociaż działa to w większości sytuacji, zdarzały się sytuacje, w których istniała konfiguracja SNAFU, a $ _SERVER ['HTTPS'] faktycznie był ustawiony na „off”. Twój kod nadal uważa to za „zaliczenie” testu, dlatego należy je zmienić, aby uwzględnić to konkretne ustawienie.
Dave Morton
6

W przypadku dowolnego systemu z wyjątkiem IIS wystarczy to do zdefiniowania własnego adresu URL witryny:

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

lub

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

zależy od tego, czego dokładnie chcesz: HTTP_HOST vs. SERVER_NAME

Eugene Zakharenko
źródło
5

W przypadku proxy SERVER_PORTmoże nie podać poprawnej wartości, więc to działało dla mnie -

$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443 || $_SERVER['HTTP_X_FORWARDED_PORT'] == 443) ? "https://" : "http://"
Harshit
źródło
4

Użyj tej zmiennej serwera, aby uzyskać szczegółowe informacje o protokole:

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

Zauważ, że ta zmienna serwera jest zawodna. Aby uzyskać więcej informacji, spójrz na: Czy $ _SERVER ['REQUEST_SCHEME'] jest solidny?

shashik493
źródło
Czy możesz dodać więcej informacji do swojego posta, a nie tylko kod? Na przykład wyjaśnij, dlaczego jest to odpowiedź na pytanie?
ndsmyter,
3

Wiem, że to stare pytanie, ale dzisiaj się z tym spotkałem, ponieważ musiałem je przetestować na mojej stronie. Wydaje się, że powyższe odpowiedzi są niepotrzebnie skomplikowane. Aby ustalić protokół witryny, wystarczy przetestować$_SERVER['HTTPS']

Jeśli protokół używa HTTPS, wówczas $_SERVER['HTTPS']zwróci „on”. Jeśli nie, zmienna pozostanie pusta. Na przykład:
// 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';
} 

Możesz użyć powyższego, aby łatwo i czysto przetestować HTTPS i odpowiednio zaimplementować. :)

Rob Stocki
źródło
2
Nie każdy serwer ma ten $ _SERVER ['HTTPS']
ChrisDeDavidMindflowAU
2

wykonał funkcję przy użyciu odpowiedzi Rid Iculous , która działała w moim systemie.

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://';
}

Mam nadzieję, że to pomoże

miyuru
źródło
2

Przetestowałem najczęściej głosowaną odpowiedź i nie działało to dla mnie , w końcu użyłem:

$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
CONvid19
źródło
Niektóre serwery sieciowe nie obsługują, $_SERVER["HTTPS"]dlatego kod może zwrócić, http://nawet jeśli powinienhttps://
nathanfranke
Jeśli serwer nie obsługuje https, dlaczego kod nadal miałby zwracać https?
CONvid19
Mój serwer obsługuje https, ale $_SERVER["HTTPS"]zmienna nigdy nie jest zdefiniowana.
nathanfranke
Jestem zdezorientowany twoimi 2 komentarzami. Prawdopodobnie lepiej, jeśli utworzysz nową odpowiedź obejmującą te szczególne przypadki. Dzięki i powodzenia!
CONvid19
2
$protocal = 'http';
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || $_SERVER['HTTPS'] == 'on') {$protocal = 'https';}


echo $protocal;
Saurabh Chandra Patel
źródło
2

Wyodrębniono z 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;
    }
}
Guillaume
źródło
0

to najlepsze rozwiązanie https lub http użyj tego:

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

Ale nie może wyświetlać https ani http, więc służy tylko do łączenia treści witryny, takich jak obraz itp.

jeśli chcesz przekierować swoją stronę w https, dodaj ten kod do pliku .htaccess:

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

Zmień adres www.twoja-domena.com na swoją nazwę dowmain.

Jhoel Rhocher
źródło
0

Oto jak to zrobić ... to jest skróconą if else wersją RID Iculous za odpowiedź ...

$protocol = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ? 'https' : 'http';
Scotty G.
źródło
0

Myślę, że cała funkcja powinna wyglądać następująco:

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

Uwagi:

  • powinieneś także poszukać HTTP_X_FORWARDED_PROTO (np. jeśli serwer proxy)
  • poleganie na porcie 443 nie jest bezpieczne (https może być obsługiwany na innym porcie)
  • REQUEST_SCHEME nie jest wiarygodny
koalaok
źródło
0

Wiem, że jestem trochę spóźniony na tę imprezę, ale jeśli wolisz nie używać $ _SERVER, ponieważ jest to zdecydowanie odradzane, a nawet dezaktywowane w niektórych frameworkach PHP; i masz serwer WWW Apache, możesz w ten sposób użyć jego natywnego polecenia: -

$protocol = apache_getenv('HTTPS') ? 'https:' : 'http:';
Jonathan
źródło