PHP Obtener el protocolo URL del sitio - http vs https

197

He escrito una pequeña función para establecer el protocolo de URL del sitio actual, pero no tengo SSL y no sé cómo probar si funciona bajo https. ¿Me puede decir si esto es correcto?

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

¿Es necesario hacerlo como se indica arriba o solo puedo hacerlo ?:

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

Bajo SSL, ¿el servidor no convierte automáticamente la url a https incluso si la url de etiqueta de anclaje usa http? ¿Es necesario verificar el protocolo?

¡Gracias!

BalusC
fuente
1
¿No sería una mejor opción para usted instalar un servidor web local y lanzar un certificado SSL autofirmado? De esa manera puedes probarlo por ti mismo.
Frazell Thomas
Sí, eso sería increíble, pero no sé cómo hacerlo.
44
Si bien esto no responde a su pregunta, una mejor solución a su problema (aunque no puedo estar seguro sin saber más) podría ser utilizar las URL relativas al protocolo .
Reese Moore
Solo una pregunta rápida ... ¿por qué estás haciendo una función si no es dinámica? No es como si alimentaste cualquier variable para cambiar la URL. ¿Por qué no definir una constante? Eso fue lo que hice. $ protocol = (! empty ($ _ SERVER ['HTTPS']) && $ _SERVER ['HTTPS']! == 'off' || $ _SERVER ['SERVER_PORT'] == 443)? "https: //": "http: //"; define ('SITE_URL', $ protocolo. $ _ SERVER ['HTTP_HOST']. '/');
HTMLGuy

Respuestas:

69

No es automatico. Tu función principal se ve bien.

profitphp
fuente
19
Cabe señalar que es automática si acaba de salir fuera del protocolo .. es decir, //mysqite.comen lugar dehttps://mysitecom
luché una vez un oso.
44
@Pamblam, // funciona muy bien a menos que su enlace esté en un correo electrónico :)
TimoSolo
O en una solicitud xhr
Lucas Morgan
86

Sé que es tarde, ¡aunque hay una forma mucho más conveniente de resolver este tipo de problema! Las otras soluciones son bastante desordenadas. así es como lo haría:

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

... o incluso sin condiciones si lo prefieres:

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

Mira esto $_SERVER["SERVER_PROTOCOL"]

Ivo
fuente
20
Esto no funciona con "https" stackoverflow.com/questions/16825243/…
wormhit
@wormhit depende principalmente de cómo esté configurado su servidor web
Ivo
¿Alguna razón por la que usas en striposlugar de strpos?
Fred
12
$_SERVER['SERVER_PROTOCOL']está hecho para almacenar HTTP/1.0o, HTTP/1.1según la versión del protocolo, ¿de qué tipo de configuración del servidor HTTP habla, almacenando httpsinformación sobre esta cadena que proviene de la consulta http?
regilero 03 de
1
¡No funciona en mi caso! $ _SERVER ['SERVER_PROTOCOL'] contiene "HTTP" (sin ninguna "S") mientras que el protocolo es https. Verificar $ _SERVER ['HTTPS'] es más apropiado.
Simon Hola
68

Esto funciona para mi

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://';
}
Ridículo
fuente
3
Esta es la solución que funciona si se usa un proxy (como en mi caso CloudFlare)
Jesús Carrera
1
Esto es correcto: no debe asumir https solo porque está utilizando el puerto 443.
Mark Fisher
24

Algunos cambios:

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

camino corto

$scheme = $_SERVER['REQUEST_SCHEME'] . '://';
softcod.com
fuente
3
REQUEST_SCHEMEno es confiable
Farnabaz
55
REQUEST_SCHEME no está disponible hasta Apache 2.4.
KenB
7

Como probar el número de puerto no es una buena práctica según mi opinión, mi solución es:

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

La HTTPSconstante devuelve TRUEsi $_SERVER['HTTPS']se establece y es igual a "1", "verdadero", "en" o "sí". Devuelve FALSO de lo contrario.

alex
fuente
Esta es probablemente la mejor respuesta. Muchas de estas respuestas serán solo en un porcentaje de situaciones. Por ejemplo, la gente solo está verificando si $ _SERVER ['HTTPS'] está configurado. Muchos marcos configuran esta variable como falsa o 'desactivada', etc., por lo tanto, verificar si simplemente está configurada no funcionará.
Daniel Dewhurst
1
Si bien esto funciona en la mayoría de las situaciones, ha habido momentos en que hubo una configuración SNAFU y $ _SERVER ['HTTPS'] en realidad se configuró en "off". Su código aún consideraría que eso "pasa" la prueba, por lo que debe modificarse para permitir esa configuración en particular.
Dave Morton
6

Para cualquier sistema, excepto IIS, esto es suficiente para definir la propia URL del sitio:

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

o

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

depende de lo que quieras exactamente: HTTP_HOST vs. SERVER_NAME

Eugene Zakharenko
fuente
5

En el caso del proxy, es SERVER_PORTposible que no proporcione el valor correcto, así que esto es lo que funcionó para mí:

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

Use esta variable de servidor para obtener los detalles del protocolo:

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

Tenga en cuenta que esta variable de servidor no es confiable. Para obtener más información, consulte: ¿Es confiable $ _SERVER ['REQUEST_SCHEME']?

shashik493
fuente
¿Puedes agregar más información a tu publicación, y no solo el código? Por ejemplo, explique por qué esta es una respuesta a la pregunta.
ndsmyter
3

Sé que esta es una vieja pregunta, pero me encontré con esto hoy ya que necesitaba hacer una prueba en mi sitio. Parece que las respuestas anteriores son innecesariamente complicadas. Para establecer el protocolo del sitio, todo lo que tiene que hacer es probar$_SERVER['HTTPS']

Si el protocolo está usando HTTPS, entonces $_SERVER['HTTPS']regresará 'on'. Si no, la variable permanecerá vacía. Por ejemplo:
// 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';
} 

Puede usar lo anterior para realizar pruebas de HTTPS de manera fácil y limpia e implementarlas en consecuencia. :)

Rob Stocki
fuente
2
No todos los servidores tienen este $ _SERVER ['HTTPS']
ChrisDeDavidMindflowAU
2

hizo una función usando la respuesta de Rid Iculous que funcionó en mi sistema.

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

Espero eso ayude

miyuru
fuente
2

He probado la respuesta más votada y no funcionó para mí , terminé usando:

$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
CONvid19
fuente
Algunos servidores web no son compatibles $_SERVER["HTTPS"]y, por lo tanto, su código puede volver http://incluso si así fuerahttps://
nathanfranke
Si el servidor no es compatible https, ¿por qué el código aún volvería https?
CONvid19
Mi servidor admite https pero la $_SERVER["HTTPS"]variable nunca está definida.
nathanfranke
Estoy confundido por tus 2 comentarios. Probablemente sea mejor si crea una nueva respuesta que cubra esos casos especiales. ¡Gracias y buena suerte!
CONvid19
2
$protocal = 'http';
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || $_SERVER['HTTPS'] == 'on') {$protocal = 'https';}


echo $protocal;
Saurabh Chandra Patel
fuente
2

Extraído 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;
    }
}
Guillaume
fuente
0

es la mejor solución de https o http, use esto:

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

Pero no puede mostrar https o http, por lo que solo se usa para vincular el contenido de su sitio como imagen, etc.

si desea redirigir su sitio en https, agregue este código en el archivo .htaccess:

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

Cambie www.your-domain.com con su nombre principal.

Jhoel Rhocher
fuente
0

Así es como lo hago ... es una versión abreviada if else de la respuesta 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';
Scotty G
fuente
0

Creo que la función completa debería verse así:

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

Notas:

  • también debe buscar HTTP_X_FORWARDED_PROTO (por ejemplo, si el servidor proxy)
  • confiar en el puerto 443 no es seguro (https podría servirse en un puerto diferente)
  • REQUEST_SCHEME no confiable
koalaok
fuente
0

Sé que llego un poco tarde a esta fiesta, pero si prefieres no usar $ _SERVER, ya que se desaconseja e incluso se desactiva en algunos marcos PHP; y tiene un servidor web apache, puede usar su comando nativo de esta manera:

$protocol = apache_getenv('HTTPS') ? 'https:' : 'http:';
Jonathan
fuente