PHP Dapatkan Protokol URL Situs - http vs https

197

Saya telah menulis sedikit fungsi untuk membuat protokol url situs saat ini, tetapi saya tidak memiliki SSL dan tidak tahu cara menguji apakah itu berfungsi di bawah https. Bisakah Anda memberi tahu saya jika ini benar?

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

Apakah perlu untuk melakukannya seperti di atas atau dapatkah saya melakukannya saja ?:

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

Di bawah SSL, bukankah server secara otomatis mengonversi url ke https bahkan jika url tag jangkar menggunakan http? Apakah perlu untuk memeriksa protokolnya?

Terima kasih!

BalusC
sumber
1
Bukankah itu pilihan yang lebih baik bagi Anda untuk menginstal server web lokal dan melemparkan sertifikat SSL yang ditandatangani sendiri di atasnya? Dengan begitu Anda bisa mengujinya sendiri.
Frazell Thomas
Ya, itu akan luar biasa, tetapi saya tidak tahu bagaimana melakukannya.
4
Meskipun ini tidak menjawab pertanyaan Anda, solusi yang lebih baik untuk masalah Anda (meskipun saya tidak yakin tanpa mengetahui lebih banyak) mungkin menggunakan URL Relatif Protokol .
Reese Moore
Hanya pertanyaan singkat ... kenapa Anda melakukan fungsi jika tidak dinamis. Ini tidak seperti Anda memberi makan vars apa pun untuk mengubah url. Mengapa tidak mendefinisikan konstanta? Itu yang saya lakukan. $ protocol = (! empty ($ _ SERVER ['HTTPS']) && $ _SERVER ['HTTPS']! == 'off' || $ _SERVER ['SERVER_PORT'] == 443)? "https: //": "http: //"; define ('SITE_URL', $ protocol. $ _ SERVER ['HTTP_HOST']. '/');
HTMLGuy
Bolehkah saya menyarankan ini? stackoverflow.com/questions/6768793/get-the-full-url-in-php
Timo Huovinen

Jawaban:

69

Ini tidak otomatis. Fungsi teratas Anda terlihat ok.

profitphp
sumber
19
Perlu dicatat bahwa itu otomatis jika Anda hanya meninggalkan protokol .. yaitu //mysqite.combukannyahttps://mysitecom
saya bergulat beruang sekali.
4
@Pamblam, // berfungsi dengan baik kecuali tautan Anda ada dalam surel :)
TimoSolo
Atau dalam permintaan xhr
Lucas Morgan
86

Saya tahu ini sudah terlambat, meskipun ada cara yang jauh lebih mudah untuk menyelesaikan masalah seperti ini! Solusi lain cukup berantakan; ini adalah bagaimana saya akan melakukannya:

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

... atau bahkan tanpa syarat jika Anda lebih suka:

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

Lihatlah $_SERVER["SERVER_PROTOCOL"]

Ivo
sumber
20
Ini tidak berfungsi dengan "https" stackoverflow.com/questions/16825243/…
wormhit
@wormhit terutama tergantung pada bagaimana server web Anda dikonfigurasi
Ivo
Ada alasan mengapa Anda menggunakan striposbukan strpos?
Fred
12
$_SERVER['SERVER_PROTOCOL']dibuat untuk menyimpan HTTP/1.0atau HTTP/1.1bergantung pada versi protokol, konfigurasi server HTTP macam apa yang Anda bicarakan, menyimpan httpsinformasi pada string ini yang berasal dari permintaan http?
regilero
1
Tidak berfungsi dalam kasus saya! $ _SERVER ['SERVER_PROTOCOL'] berisi "HTTP" (tanpa "S") sementara protokolnya adalah https. Memeriksa $ _SERVER ['HTTPS'] lebih tepat.
Simon Hai
68

Ini bekerja untuk saya

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://';
}
Singkirkan Iculous
sumber
3
Ini adalah solusi yang berfungsi jika menggunakan proxy (seperti dalam kasus saya CloudFlare)
Jesús Carrera
1
Ini benar - Anda tidak boleh menganggap https hanya karena Anda menggunakan port 443.
Mark Fisher
24

Beberapa perubahan:

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

jalan pendek

$scheme = $_SERVER['REQUEST_SCHEME'] . '://';
softcod.com
sumber
3
REQUEST_SCHEMEtidak dapat diandalkan
Farnabaz
5
REQUEST_SCHEME tidak tersedia hingga Apache 2.4.
KenB
7

Karena pengujian nomor port bukanlah praktik yang baik menurut saya, solusi saya adalah:

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

Pengembalian HTTPSkonstan TRUEjika $_SERVER['HTTPS']disetel dan sama dengan "1", "true", "on" atau "yes". Mengembalikan FALSE sebaliknya.

alex
sumber
Ini mungkin jawaban terbaik. Banyak dari jawaban-jawaban ini akan hanya dalam persentase situasi. Misalnya, orang hanya memeriksa apakah $ _SERVER ['HTTPS'] disetel. Banyak kerangka kerja menetapkan variabel ini sebagai false atau 'off' dll, oleh karena itu memeriksa apakah itu hanya mengatur tidak akan berfungsi.
Daniel Dewhurst
1
Meskipun ini berfungsi di sebagian besar situasi, ada kalanya ada konfigurasi SNAFU dan $ _SERVER ['HTTPS'] sebenarnya disetel ke "off". Kode Anda masih akan menganggap itu sebagai "lulus" tes, jadi harus diubah untuk memungkinkan pengaturan tertentu.
Dave Morton
6

Untuk sistem apa pun kecuali IIS ini cukup untuk mendefinisikan URL sendiri situs:

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

atau

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

tergantung pada apa yang Anda inginkan: HTTP_HOST vs. SERVER_NAME

Eugene Zakharenko
sumber
5

Dalam hal proxy yang SERVER_PORTmungkin tidak memberikan nilai yang benar jadi inilah yang bekerja untuk saya -

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

Gunakan variabel server ini untuk mendapatkan detail protokol:

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

Perhatikan bahwa variabel server ini tidak dapat diandalkan. Untuk informasi lebih lanjut, lihat: Apakah $ _SERVER ['REQUEST_SCHEME'] dapat diandalkan?

shashik493
sumber
Bisakah Anda menambahkan lebih banyak informasi ke posting Anda, dan bukan hanya kode? Misalnya menjelaskan mengapa ini merupakan jawaban untuk pertanyaan?
ndsmyter
3

Saya tahu ini adalah pertanyaan lama tetapi saya menemukan ini hari ini karena saya perlu menguji ini di situs saya. Tampaknya jawaban di atas tidak perlu rumit. Untuk membuat protokol situs, yang harus Anda lakukan adalah menguji$_SERVER['HTTPS']

Jika protokol menggunakan HTTPS, maka $_SERVER['HTTPS']akan kembali 'on'. Jika tidak, variabel akan tetap kosong. Sebagai contoh:
// 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';
} 

Anda dapat menggunakan hal di atas untuk menguji HTTPS dengan mudah dan bersih dan menerapkannya. :)

Rob Stocki
sumber
2
Tidak setiap server memiliki $ _SERVER ['HTTPS'] ini
ChrisDeDavidMindflowAU
2

membuat fungsi menggunakan jawaban Rid Iculous yang bekerja pada sistem saya.

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

Semoga ini bisa membantu

miyuru
sumber
2

Saya telah menguji answe r yang paling banyak dipilih dan tidak berhasil , saya akhirnya menggunakan:

$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
HUBUNGI19
sumber
Beberapa server web tidak mendukung $_SERVER["HTTPS"]dan oleh karena itu kode Anda dapat kembali http://walaupun seharusnyahttps://
nathanfranke
Jika server tidak mendukung https, mengapa kode masih kembali https?
CONvid19
Server saya mendukung https tetapi $_SERVER["HTTPS"]variabelnya tidak pernah ditentukan.
nathanfranke
Saya bingung dengan 2 komentar Anda. Mungkin lebih baik jika Anda membuat jawaban baru yang mencakup kasus-kasus khusus itu. Terima kasih dan semoga berhasil!
CONvid19
2
$protocal = 'http';
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || $_SERVER['HTTPS'] == 'on') {$protocal = 'https';}


echo $protocal;
Saurabh Chandra Patel
sumber
2

Diambil dari 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
sumber
0

ini solusi terbaik https atau http gunakan ini:

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

Tetapi tidak dapat menampilkan https atau http, jadi itu hanya digunakan untuk menautkan konten situs Anda seperti gambar, dll.

jika ingin mengarahkan ulang situs Anda di https, tambahkan kode ini dalam file .htaccess:

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

Ubah www.domain-anda.com dengan nama mas kawin Anda.

Jhoel Rhocher
sumber
0

Inilah cara saya melakukannya ... ini adalah versi singkat if else dari jawaban 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
sumber
0

Saya pikir func lengkap harus terlihat seperti:

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

Catatan:

  • Anda juga harus mencari HTTP_X_FORWARDED_PROTO (mis. jika server proxy)
  • mengandalkan port 443 tidak aman (https dapat dilayani di port yang berbeda)
  • REQUEST_SCHEME tidak dapat diandalkan
koalaok
sumber
0

Saya tahu saya agak terlambat ke pesta ini, tetapi jika Anda lebih suka tidak menggunakan $ _SERVER karena sangat tidak disarankan, dan bahkan dinonaktifkan pada beberapa kerangka kerja PHP; dan Anda memiliki server web apache, Anda dapat menggunakannya dengan perintah asli: -

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