PHP Get Site URL Protocol-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がhttpを使用していても、サーバーはURLをhttpsに自動的に変換しませんか?プロトコルを確認する必要はありますか?

ありがとうございました!


1
ローカルWebサーバーをインストールして、自己署名SSL証明書をそのサーバーにスローする方がよいオプションではないでしょうか。そうすれば、自分でテストできます。
Frazell Thomas

はい、それは素晴らしいことですが、私はそれを行う方法がわかりません。

4
これはあなたの質問に答えませんが、あなたの問題に対するより良い解決策(私はもっと知らなければ確信が持てませんが)はプロトコル相対URLを使うことかもしれません。
リースムーア

簡単な質問です。動的でない関数をどうやって実行するのですか。URLを変更するために変数をフィードするようなものではありません。定数を定義しないのはなぜですか?それは私がやったことです。$ protocol =(!empty($ _ SERVER ['HTTPS'])&& $ _SERVER ['HTTPS']!== 'off' || $ _SERVER ['SERVER_PORT'] == 443)?"https://": "http://"; define( 'SITE_URL'、$ protocol。$ _ SERVER ['HTTP_HOST']。 '/');
HTMLGuy 2013年

回答:



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サーバ設定のどのような話をしないhttpsHTTPクエリから来て、この文字列の情報を?
regilero 2015

1
私の場合はうまくいきません!$ _SERVER ['SERVER_PROTOCOL']には、プロトコルがhttpsの場合、「HTTP」(「S」なし)が含まれます。$ _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のように)プロキシを使用している場合は機能するソリューションです
ヘスス・カレラ

1
これは正しいです-あなたはポート443を使用しているという理由だけで、HTTPSを仮定するべきではありません
マーク・フィッシャー

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」、「true」、「on」、または「yes」に設定されている場合に返されます。それ以外の場合はFALSEを返します。


これがおそらく最良の答えです。これらの答えの多くは、状況の割合でのみになります。たとえば、$ _ SERVER ['HTTPS']が設定されているかどうかを確認しているだけです。多くのフレームワークはこの変数をfalseや 'off'などに設定するため、単に設定されているかどうかのチェックは機能しません。
Daniel Dewhurst 2017年

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 2015

3

私はこれが古い質問であることを知っていますが、自分のサイトでこれをテストする必要があったので、今日これに遭遇しました。上記の答えは不必要に複雑なようです。サイトプロトコルを確立するには、テストするだけです$_SERVER['HTTPS']

プロトコルがHTTPSを使用している場合、$_SERVER['HTTPS']「on」を返します。そうでない場合、変数は空のままになります。例えば:
// 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 '13 / 11/18

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

私がテストしたほとんどがanswe投票 rは、それは私のために動作しませんでした、私が使用して終了しました:

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

一部のWebサーバーはサポートしていない$_SERVER["HTTPS"]ため、コードがhttp://https://
正常に返さ

サーバーがをサポートしていない場合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を自分のダウメイン名に変更します。


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を使用したくない場合は強くお勧めしません。そしてあなたがApache Webサーバーを持っている、あなたはそれは以下のようなものをネイティブコマンドの使用することができます-

$protocol = apache_getenv('HTTPS') ? 'https:' : 'http:';
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.