PHP รับโปรโตคอล URL ของเว็บไซต์ - http กับ https


197

ฉันได้เขียนฟังก์ชั่นเล็กน้อยเพื่อสร้างโพรโทคอล url ไซต์ปัจจุบัน แต่ฉันไม่มี SSL และไม่รู้วิธีการทดสอบว่าทำงานได้ภายใต้ https หรือไม่ คุณบอกฉันได้ไหมว่าสิ่งนี้ถูกต้อง?

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

จำเป็นหรือไม่ที่จะทำเหมือนข้างบนหรือฉันสามารถทำมันได้หรือไม่:

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

ภายใต้ SSL เซิร์ฟเวอร์จะไม่แปลง URL เป็น https โดยอัตโนมัติแม้ว่า URL ของแท็กจุดยึดจะใช้ http หรือไม่ จำเป็นต้องตรวจสอบโปรโตคอลหรือไม่

ขอบคุณ!


1
มันจะเป็นตัวเลือกที่ดีกว่าหรือไม่สำหรับคุณที่จะติดตั้งเว็บเซิร์ฟเวอร์ในพื้นที่และส่งใบรับรอง SSL ที่ลงชื่อด้วยตนเองลงไป? ด้วยวิธีนี้คุณสามารถทดสอบด้วยตัวเอง
Frazell Thomas

ใช่แล้วมันยอดเยี่ยม แต่ฉันไม่รู้จะทำยังไง

4
แม้ว่าสิ่งนี้จะไม่ตอบคำถามของคุณ แต่ทางออกที่ดีกว่าสำหรับปัญหาของคุณ (แม้ว่าฉันจะไม่แน่ใจหากไม่ทราบเพิ่มเติม) อาจใช้URL ที่เกี่ยวข้องกับโพรโทคอ
Reese Moore

แค่คำถามสั้น ๆ ... ทำไมคุณถึงทำฟังก์ชั่นถ้ามันไม่ได้เป็นแบบไดนามิก มันไม่เหมือนกับที่คุณป้อน vars เพื่อเปลี่ยน URL ทำไมไม่กำหนดค่าคงที่? นั่นคือสิ่งที่ฉันทำ $ protocol = (! empty ($ _ SERVER ['HTTPS']) && $ _SERVER ['HTTPS']! == 'ปิด' || $ _SERVER ['SERVER_PORT'] == 443)? "https: //": "http: //"; define ('SITE_URL', $ protocol. $ _ SERVER ['HTTP_HOST']. '/');
HTMLGuy

ฉันขอแนะนำสิ่งนี้ได้ไหม stackoverflow.com/questions/6768793/get-the-full-url-in-php
Timo Huovinen

คำตอบ:


69

มันไม่ได้เป็นไปโดยอัตโนมัติ ฟังก์ชั่นชั้นนำของคุณดูโอเค


19
น่าสังเกตว่ามันเป็นแบบอัตโนมัติหากคุณเพิ่งออกจากโปรโตคอล .. เช่น//mysqite.comแทนที่จะเป็นhttps://mysitecom
ฉันปล้ำหมีหนึ่งครั้ง

4
@Pamblam, // งานได้ดียกเว้นในกรณีที่การเชื่อมโยงของคุณอยู่ในอีเมล :)
TimoSolo

หรือตามคำขอ xhr
Lucas Morgan

86

ฉันรู้ว่ามันมาสายแม้ว่าจะมีวิธีที่สะดวกกว่าในการแก้ปัญหาแบบนี้! โซลูชันอื่น ๆ ค่อนข้างยุ่ง นี่คือวิธีที่ฉันจะทำ:

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

... หรือแม้กระทั่งโดยไม่มีเงื่อนไขหากคุณต้องการ:

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

มองไปที่ $_SERVER["SERVER_PROTOCOL"]


20
สิ่งนี้ใช้ไม่ได้กับ "https" stackoverflow.com/questions/16825243/ …
Wormhit

@wormhit ส่วนใหญ่ขึ้นอยู่กับการกำหนดค่าเว็บเซิร์ฟเวอร์ของคุณว่า
Ivo

เหตุผลใดที่คุณใช้striposแทนstrposหรือไม่
Fred

12
$_SERVER['SERVER_PROTOCOL']ถูกสร้างขึ้นเพื่อจัดเก็บHTTP/1.0หรือHTTP/1.1ขึ้นอยู่กับรุ่นของโพรโทคอลที่คุณพูดถึงการกำหนดค่าเซิร์ฟเวอร์ HTTP ประเภทใดการจัดเก็บhttpsข้อมูลเกี่ยวกับสตริงนี้มาจากการสืบค้น http
regilero

1
ไม่ทำงานในกรณีของฉัน! $ _SERVER ['SERVER_PROTOCOL'] มี "HTTP" (ไม่มี "S") ในขณะที่โปรโตคอลคือ https การตรวจสอบ $ _SERVER ['HTTPS'] เหมาะสมกว่า
Simon Hi

68

มันใช้งานได้สำหรับฉัน

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
นี่เป็นวิธีแก้ปัญหาที่ใช้งานได้หากใช้พร็อกซี (เช่นในกรณีของฉัน CloudFlare)
Jesús Carrera

1
สิ่งนี้ถูกต้องคุณไม่ควรถือว่า https เพียงเพราะคุณใช้พอร์ต 443
ทำเครื่องหมายว่าฟิชเชอร์

24

การเปลี่ยนแปลงบางอย่าง:

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


7

เนื่องจากการทดสอบหมายเลขพอร์ตไม่ใช่วิธีปฏิบัติที่ดีตามตัวฉันโซลูชันของฉันคือ:

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

HTTPSผลตอบแทนคงที่TRUEหาก$_SERVER['HTTPS']มีการตั้งค่าและเท่ากับ "1", "ความจริง", "บน" หรือ "ใช่" ส่งคืน FALSE เป็นอย่างอื่น


นี่อาจเป็นคำตอบที่ดีที่สุด คำตอบเหล่านี้จำนวนมากจะอยู่ในสถานการณ์เท่านั้น ตัวอย่างเช่นผู้คนกำลังตรวจสอบว่ามีการตั้งค่า $ _SERVER ['HTTPS'] เฟรมเวิร์กจำนวนมากตั้งค่าตัวแปรนี้เป็นเท็จหรือ 'ปิด' ฯลฯ ดังนั้นการตรวจสอบว่าการตั้งค่าเพียงอย่างเดียวจะไม่ทำงาน
Daniel Dewhurst

1
ในขณะที่การทำงานภายใต้สถานการณ์ส่วนใหญ่มีหลายครั้งที่มีการกำหนดค่า SNAFU และ $ _SERVER ['HTTPS'] ถูกตั้งค่าเป็น "ปิด" รหัสของคุณจะยังคงถือว่าเป็น "ผ่าน" การทดสอบดังนั้นควรแก้ไขเพื่อให้การตั้งค่านั้น
เดฟมอร์ตัน

6

สำหรับระบบใด ๆ ยกเว้น IIS นี่ค่อนข้างเพียงพอที่จะกำหนด URL ของไซต์ด้วยตนเอง:

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

หรือ

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

ขึ้นอยู่กับสิ่งที่คุณต้องการ: HTTP_HOST กับ SERVER_NAME


5

ในกรณีของพร็อกซี่SERVER_PORTอาจไม่ให้ค่าที่ถูกต้องดังนั้นนี่คือสิ่งที่ทำงานสำหรับฉัน -

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

4

ใช้ตัวแปรเซิร์ฟเวอร์นี้เพื่อรับรายละเอียดโปรโตคอล:

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

โปรดทราบว่าตัวแปรเซิร์ฟเวอร์นี้ไม่น่าเชื่อถือ สำหรับข้อมูลเพิ่มเติมดูที่: $ _SERVER ['REQUEST_SCHEME'] เชื่อถือได้หรือไม่


คุณสามารถเพิ่มข้อมูลเพิ่มเติมในโพสต์ของคุณและไม่เพียง แต่รหัส ตัวอย่างเช่นอธิบายว่าทำไมนี่คือคำตอบของคำถาม
ndsmyter

3

ฉันรู้ว่านี่เป็นคำถามเก่า แต่วันนี้ฉันเจอเพราะฉันต้องการทดสอบในเว็บไซต์ของฉัน ดูเหมือนว่าคำตอบข้างต้นมีความซับซ้อนโดยไม่จำเป็น เพื่อสร้างโปรโตคอลเว็บไซต์สิ่งที่คุณต้องทำคือทดสอบ$_SERVER['HTTPS']

หากโปรโตคอลกำลังใช้ HTTPS แล้ว$_SERVER['HTTPS']จะส่งคืน 'เปิด' หากไม่มีตัวแปรจะยังคงว่างเปล่า ตัวอย่างเช่น:
// 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';
} 

คุณสามารถใช้ข้อมูลด้านบนเพื่อทดสอบ HTTPS และนำไปใช้อย่างง่ายดายและอย่างเรียบร้อย :)


2
ไม่ใช่ทุกเซิร์ฟเวอร์ที่มี $ _SERVER ['HTTPS'] นี้
ChrisDeDavidMindflowAU

2

สร้างฟังก์ชั่นโดยใช้คำตอบของRid Iculousซึ่งทำงานบนระบบของฉัน

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

หวังว่ามันจะช่วย


2

ฉันทดสอบคำตอบที่ได้รับการโหวตมากที่สุดและใช้ไม่ได้ผลฉันลงเอยด้วยการใช้:

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

เว็บเซิร์ฟเวอร์บางแห่งไม่สนับสนุน$_SERVER["HTTPS"]และดังนั้นรหัสของคุณอาจส่งคืนhttp://แม้ว่าจะเป็นhttps://
nathanfranke

ถ้าเซิร์ฟเวอร์ไม่สนับสนุนhttpsจะทำไมรหัสยังคงกลับมาhttps?
CONVID19

เซิร์ฟเวอร์ของฉันรองรับ https แต่$_SERVER["HTTPS"]ไม่เคยกำหนดตัวแปร
nathanfranke

ฉันสับสนกับ 2 ความคิดเห็นของคุณ มันอาจจะดีกว่าถ้าคุณสร้างคำตอบใหม่ที่ครอบคลุมกรณีพิเศษเหล่านั้น ขอขอบคุณและขอให้โชคดี!
CONVID19


2

สกัดจาก 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

มันเป็นทางออกที่ดีที่สุดของ https หรือ http ใช้สิ่งนี้:

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

แต่ไม่สามารถแสดง https หรือ http ดังนั้นจะใช้เพื่อเชื่อมโยงเนื้อหาไซต์ของคุณเช่นรูปภาพ ฯลฯ เท่านั้น

หากต้องการเปลี่ยนเส้นทางเว็บไซต์ของคุณใน https ให้เพิ่มรหัสนี้ในไฟล์. htaccess:

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

เปลี่ยนwww.your-domain.comด้วยชื่อ dowmain ของคุณ


0

นี่คือวิธีที่ฉันทำ ... มันเป็นคำตอบของRid Iculousรุ่นย่อ ...if else

$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

ฉันคิดว่า func ที่สมบูรณ์ควรมีลักษณะดังนี้:

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

หมายเหตุ:

  • คุณควรมองหา HTTP_X_FORWARDED_PROTO (เช่นถ้าพร็อกซีเซิร์ฟเวอร์)
  • การใช้พอร์ต 443 ไม่ปลอดภัย (https สามารถแสดงบนพอร์ตอื่น)
  • REQUEST_SCHEME ไม่น่าเชื่อถือ

0

ฉันรู้ว่าฉันมาช้าไปงานปาร์ตี้นี้ แต่ถ้าคุณไม่ชอบใช้ $ _SERVER มากเพราะมันท้อแท้อย่างยิ่งและปิดการใช้งานในบางเฟรมเวิร์ค PHP และคุณมีเว็บเซิร์ฟเวอร์ apache คุณสามารถใช้มันเป็นคำสั่งดั้งเดิม: -

$protocol = apache_getenv('HTTPS') ? 'https:' : 'http:';
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.