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!


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

Jawaban:


69

Ini tidak otomatis. Fungsi teratas Anda terlihat ok.


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"]


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

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

16

jalan pendek

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

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.


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


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://"

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?


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. :)


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


2

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

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

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;

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

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.


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

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

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:';
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.