PHP Get Site URL Protocol - http vs https


197

J'ai écrit une petite fonction pour établir le protocole d'URL du site actuel mais je n'ai pas SSL et je ne sais pas comment tester s'il fonctionne sous https. Pouvez-vous me dire si c'est correct?

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

Est-il nécessaire de le faire comme ci-dessus ou puis-je simplement le faire comme?:

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

Sous SSL, le serveur ne convertit-il pas automatiquement l'URL en https même si l'URL de la balise d'ancrage utilise http? Faut-il vérifier le protocole?

Je vous remercie!


1
Ne serait-ce pas une meilleure option pour vous d'installer un serveur Web local et d'y jeter un certificat SSL auto-signé? De cette façon, vous pouvez le tester par vous-même.
Frazell Thomas

Oui, ce serait génial, mais je ne sais pas comment le faire.

4
Bien que cela ne réponde pas à votre question, une meilleure solution à votre problème (bien que je ne puisse pas être sûr sans en savoir plus) pourrait être d'utiliser des URL relatives au protocole .
Reese Moore

Juste une question rapide ... comment se fait-il que vous réalisiez une fonction si elle n'est pas dynamique. Ce n'est pas comme si vous le nourrissiez de vars pour changer l'url. Pourquoi ne pas définir une constante? C'est ce que j'ai fait. $ protocol = (! empty ($ _ SERVER ['HTTPS']) && $ _SERVER ['HTTPS']! == 'off' || $ _SERVER ['SERVER_PORT'] == 443)? "https: //": "http: //"; define ('SITE_URL', $ protocol. $ _ SERVER ['HTTP_HOST']. '/');
HTMLGuy

Réponses:


69

Ce n'est pas automatique. Votre fonction supérieure semble correcte.


19
vaut la peine de noter que c'est automatique si vous laissez juste le protocole .. c'est-à-dire //mysqite.comau lieu dehttps://mysitecom
j'ai lutté un ours une fois.

4
@Pamblam, // fonctionne très bien à moins que votre lien ne soit dans un e-mail :)
TimoSolo

Ou dans une demande xhr
Lucas Morgan

86

Je sais qu'il est tard, bien qu'il existe un moyen beaucoup plus pratique de résoudre ce genre de problème! Les autres solutions sont assez compliquées; voici comment je le ferais:

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

... ou même sans condition si vous préférez:

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

Jettes un coup d'oeil à $_SERVER["SERVER_PROTOCOL"]


20
Cela ne fonctionne pas avec "https" stackoverflow.com/questions/16825243/…
wormhit

@wormhit, cela dépend principalement de la configuration de votre serveur Web
Ivo

Une raison pour laquelle vous utilisez striposau lieu de strpos?
Fred

12
$_SERVER['SERVER_PROTOCOL']est fait pour stocker HTTP/1.0ou HTTP/1.1selon la version du protocole, de quel type de configuration de serveur HTTP parlez-vous, stockant des httpsinformations sur cette chaîne provenant de la requête http?
regilero

1
Ne fonctionne pas dans mon cas! $ _SERVER ['SERVER_PROTOCOL'] contient "HTTP" (sans aucun "S") tandis que le protocole est https. La vérification de $ _SERVER ['HTTPS'] est plus appropriée.
Simon Hi

68

Ça marche pour moi

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
Ceci est la solution qui fonctionne si vous utilisez un proxy (comme dans mon cas CloudFlare)
Jesús Carrera

1
C'est correct - vous ne devez pas supposer https simplement parce que vous utilisez le port 443.
Mark Fisher

24

Quelques changements:

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

16

chemin court

$scheme = $_SERVER['REQUEST_SCHEME'] . '://';

3
REQUEST_SCHEMEn'est pas fiable
Farnabaz

5
REQUEST_SCHEME n'est pas disponible avant Apache 2.4.
KenB

7

Parce que tester le numéro de port n'est pas une bonne pratique selon moi, ma solution est:

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

La HTTPSconstante renvoie TRUEif $_SERVER['HTTPS']est définie et égale à "1", "true", "on" ou "yes". Renvoie FAUX sinon.


C'est probablement la meilleure réponse. Beaucoup de ces réponses ne le seront que dans un pourcentage de situations. Par exemple, les gens vérifient simplement si $ _SERVER ['HTTPS'] est défini. De nombreux frameworks définissent cette variable comme false ou «off», etc., donc vérifier si elle est simplement définie ne fonctionnera pas.
Daniel Dewhurst

1
Bien que cela fonctionne dans la plupart des situations, il y a eu des moments où il y avait une configuration SNAFU et $ _SERVER ['HTTPS'] était en fait réglé sur "off". Votre code considère toujours que cela "réussit" le test et doit donc être modifié pour permettre ce réglage particulier.
Dave Morton

6

Pour tout système sauf IIS, cela suffit pour définir l'URL du site:

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

ou

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

dépend de ce que vous voulez exactement: HTTP_HOST vs SERVER_NAME


5

En cas de procuration, le SERVER_PORTpeut ne pas donner la valeur correcte, c'est donc ce qui a fonctionné pour moi -

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

4

Utilisez cette variable de serveur pour obtenir les détails du protocole:

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

Notez que cette variable de serveur n'est pas fiable. Pour plus d'informations, consultez: $ _SERVER ['REQUEST_SCHEME'] est-il fiable?


Pouvez-vous ajouter plus d'informations à votre message, et pas seulement le code? Par exemple, expliquez pourquoi il s'agit d'une réponse à la question?
ndsmyter

3

Je sais que c'est une vieille question, mais je suis tombé dessus aujourd'hui car j'avais besoin de tester cela sur mon site. Il semble que les réponses ci-dessus soient inutilement compliquées. Pour établir le protocole du site, il vous suffit de tester$_SERVER['HTTPS']

Si le protocole utilise HTTPS, puis $_SERVER['HTTPS']reviendra «on». Sinon, la variable restera vide. Par exemple:
// 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';
} 

Vous pouvez utiliser ce qui précède pour tester facilement et proprement le protocole HTTPS et l'implémenter en conséquence. :)


2
Tous les serveurs n'ont pas ce $ _SERVER ['HTTPS']
ChrisDeDavidMindflowAU

2

fait une fonction en utilisant la réponse de Rid Iculous qui fonctionnait sur mon système.

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

J'espère que ça aide


2

J'ai testé la réponse la plus votée et cela n'a pas fonctionné pour moi , j'ai fini par utiliser:

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

Certains serveurs Web ne prennent pas en charge $_SERVER["HTTPS"]et votre code peut donc revenir http://même s'il devrait l'êtrehttps://
nathanfranke

Si le serveur ne prend pas en charge https, pourquoi le code retournerait-il quand même https?
CONvid19

Mon serveur prend en charge https mais la $_SERVER["HTTPS"]variable n'est jamais définie.
nathanfranke

Je suis confus par vos 2 commentaires. Il est probablement préférable de créer une nouvelle réponse qui couvre ces cas particuliers. Merci et bonne chance!
CONvid19

2
$protocal = 'http';
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || $_SERVER['HTTPS'] == 'on') {$protocal = 'https';}


echo $protocal;

2

Extrait de 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

c'est la meilleure solution de https ou http, utilisez ceci:

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

Mais ne peut pas afficher https ou http, donc il ne sert qu'à lier le contenu de votre site comme l'image, etc.

si vous souhaitez rediriger votre site en https, ajoutez ce code dans le fichier .htaccess:

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

Changez www.your-domain.com avec votre nom dowmain.


0

Voici comment je le fais ... c'est une version abrégée if else de la réponse de Rid Iculous ...

$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

Je pense que la fonction complète devrait ressembler à:

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

Remarques:

  • vous devez également rechercher HTTP_X_FORWARDED_PROTO (par exemple si le serveur proxy)
  • compter sur le port 443 n'est pas sûr (https pourrait être servi sur un port différent)
  • REQUEST_SCHEME pas fiable

0

Je sais que je suis un peu en retard à cette fête, mais si vous préférez de loin ne pas utiliser $ _SERVER car il est fortement déconseillé, et même désactivé sur certains frameworks PHP; et vous avez un serveur web apache, vous pouvez utiliser sa commande native ainsi: -

$protocol = apache_getenv('HTTPS') ? 'https:' : 'http:';
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.