Protocolo de URL do site Get PHP - http vs https

197

Eu escrevi uma pequena função para estabelecer o protocolo de URL do site atual, mas não tenho SSL e não sei como testar se funciona em https. Você pode me dizer se isso está correto?

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

É necessário fazê-lo como acima ou posso fazê-lo como ?:

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

Sob SSL, o servidor não converte automaticamente o URL para https, mesmo que o URL da tag de âncora esteja usando http? É necessário verificar o protocolo?

Obrigado!

BalusC
fonte
1
Não seria uma opção melhor para você instalar um servidor da Web local e lançar um certificado SSL autoassinado nele? Dessa forma, você pode testá-lo por si mesmo.
precisa saber é o seguinte
Sim, isso seria incrível, mas não sei como fazê-lo.
4
Embora isso não responda à sua pergunta, uma solução melhor para o seu problema (embora eu não tenha certeza sem saber mais) pode ser usar URLs relativas ao protocolo .
Reese Moore
Apenas uma pergunta rápida ... como é que você está fazendo uma função se não é dinâmica. Não é como você alimentá-lo para alterar o URL. Por que não definir uma constante? Isso é o que eu fiz. $ protocol = (! vazio ($ _ SERVER ['HTTPS']) && $ _SERVER ['HTTPS']! == 'desativado' || $ _SERVER ['SERVER_PORT'] == 443)? "https: //": "http: //"; define ('SITE_URL', $ protocol. $ _ SERVER ['HTTP_HOST']. '/');
usar o seguinte código
Posso sugerir isso? Você está em
Página

Respostas:

69

Não é automático. Sua função principal parece boa.

profitphp
fonte
19
vale a pena notar que é automático se você simplesmente deixar de lado o protocolo ... ou seja, em //mysqite.comvez dehttps://mysitecom
eu lutei com um urso uma vez.
4
@Pamblam, // funciona muito bem a menos que seu link está em um e-mail :)
TimoSolo
Ou por um pedido xhr
Lucas Morgan
86

Sei que é tarde, embora exista uma maneira muito mais conveniente de resolver esse tipo de problema! As outras soluções são bastante confusas; é assim que eu faria:

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

... ou mesmo sem condição, se você preferir:

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

Dê uma olhada em $_SERVER["SERVER_PROTOCOL"]

Ivo
fonte
20
Este trabalho não faça com "https" stackoverflow.com/questions/16825243/...
wormhit
@wormhit isso depende principalmente de como seu servidor web está configurado embora
Ivo
Alguma razão para você usar em striposvez de strpos?
Fred
12
$_SERVER['SERVER_PROTOCOL']feito para armazenar HTTP/1.0ou, HTTP/1.1dependendo da versão do protocolo, de que tipo de configuração do servidor HTTP você se refere, armazenando httpsinformações sobre essa cadeia de caracteres provenientes da consulta http?
regilero
1
Não funciona no meu caso! $ _SERVER ['SERVER_PROTOCOL'] contém "HTTP" (sem nenhum "S") enquanto o protocolo é https. Verificar $ _SERVER ['HTTPS'] é mais apropriado.
Simon Hi
68

Isso funciona para mim

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://';
}
Livrar Iculous
fonte
3
Esta é a solução que funciona se estiver usando um proxy (como no meu caso CloudFlare)
Jesús Carrera
1
Isso é correto - você não deve presumir https só porque você está usando a porta 443.
Mark Fisher
24

Algumas mudanças:

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

atalho

$scheme = $_SERVER['REQUEST_SCHEME'] . '://';
softcod.com
fonte
3
REQUEST_SCHEMEnão é confiável
Farnabaz
5
REQUEST_SCHEME não está disponível até o Apache 2.4.
KenB
7

Como o número da porta de teste não é uma boa prática, minha solução é:

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

A HTTPSconstante retorna TRUEse $_SERVER['HTTPS']é configurada e é igual a "1", "true", "on" ou "yes". Retorna FALSE caso contrário.

alex
fonte
Esta é provavelmente a melhor resposta. Muitas dessas respostas serão apenas em uma porcentagem de situações. Por exemplo, as pessoas estão apenas verificando se $ _SERVER ['HTTPS'] está definido. Muitos frameworks definem essa variável como false ou 'off' etc, portanto, verificar se está simplesmente configurado não funcionará.
precisa
1
Enquanto isso funciona na maioria das situações, houve momentos em que houve uma configuração SNAFU e $ _SERVER ['HTTPS'] foi realmente definido como "off". Seu código ainda consideraria que "passando" no teste, portanto, deve ser alterado para permitir essa configuração específica.
Dave Morton
6

Para qualquer sistema, exceto o IIS, isso é suficiente para definir o URL próprio do site:

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

ou

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

depende do que você deseja exatamente: HTTP_HOST vs. SERVER_NAME

Eugene Zakharenko
fonte
5

No caso de proxy, SERVER_PORTpode não fornecer o valor correto, e foi isso que funcionou para mim -

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

Use esta variável de servidor para obter os detalhes do protocolo:

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

Observe que essa variável do servidor não é confiável. Para mais informações, consulte: $ _SERVER ['REQUEST_SCHEME'] é confiável?

shashik493
fonte
Você pode adicionar mais informações à sua postagem, e não apenas o código? Por exemplo, explique por que essa é uma resposta para a pergunta?
Ndsmyter 08/07/2015
3

Sei que essa é uma pergunta antiga, mas me deparei com isso hoje, pois precisava testar isso no meu site. Parece que as respostas acima são desnecessariamente complicadas. Para estabelecer o protocolo do site, tudo que você precisa fazer é testar$_SERVER['HTTPS']

Se o protocolo estiver usando HTTPS, ele $_SERVER['HTTPS']retornará 'on'. Caso contrário, a variável permanecerá vazia. Por exemplo:
// 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';
} 

Você pode usar o acima para testar de maneira fácil e limpa o HTTPS e implementar de acordo. :)

Rob Stocki
fonte
2
Nem todos os servidores possuem esse $ _SERVER ['HTTPS'] #
4911 ChrisDeDavidMindflowAU
2

fez uma função usando a resposta do Rid Iculous que funcionou no meu 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 que ajude

miyuru
fonte
2

Testei a resposta mais votada e não funcionou para mim , acabei usando:

$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
CONvid19
fonte
Alguns servidores web não suportam $_SERVER["HTTPS"]e, portanto, seu código pode retornar http://mesmo que deva serhttps://
nathanfranke
Se o servidor não suportar https, por que o código ainda retornará https?
CONvid19 21/01
Meu servidor suporta https, mas a $_SERVER["HTTPS"]variável nunca é definida.
nathanfranke 21/01
Estou confuso com seus 2 comentários. Provavelmente é melhor se você criar uma nova resposta que cubra esses casos especiais. Obrigado e boa sorte!
CONvid19 21/01
2
$protocal = 'http';
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || $_SERVER['HTTPS'] == 'on') {$protocal = 'https';}


echo $protocal;
Saurabh Chandra Patel
fonte
2

Extraído do 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
fonte
0

é a melhor solução de https ou http:

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

Mas não pode exibir https ou http, portanto, use apenas para vincular o conteúdo do site, como imagem etc.

se quiser redirecionar seu site em https, adicione este código no arquivo .htaccess:

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

Mude www.seudominio.com com o seu nome de domínio.

Jhoel Rhocher
fonte
0

Aqui está como eu faço isso ... é uma versão abreviada da resposta if elsede 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
fonte
0

Eu acho que a função completa deve se parecer com:

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:

  • você deve procurar também por HTTP_X_FORWARDED_PROTO (por exemplo, se servidor proxy)
  • confiar na porta 443 não é seguro (https pode ser servido em uma porta diferente)
  • REQUEST_SCHEME não confiável
koalaok
fonte
0

Eu sei que estou um pouco atrasado para esta festa, mas se você preferir não usar o $ _SERVER, pois é altamente desencorajado e até desativado em algumas estruturas PHP; e você tem um servidor web apache, pode usar o comando nativo da seguinte forma: -

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