Windows / IISサーバーで現在のページの完全なURLを取得するにはどうすればよいですか?


137

WordPressインストールをWindows / IISサーバーの新しいフォルダーに移動しました。PHPで301リダイレクトを設定していますが、動作していないようです。私の投稿URLの形式は次のとおりです。

http:://www.example.com/OLD_FOLDER/index.php/post-title/

/post-title/URLの一部を取得する方法がわかりません。

$_SERVER["REQUEST_URI"]-誰もが推奨しているようです-空の文字列を返しています。$_SERVER["PHP_SELF"]ただ戻るだけindex.phpです。これはなぜですか、どうすれば修正できますか?


24
print_r($ _ SERVER)を実行して、使用可能なデータを確認してください。完全なURLを取得できる場合は、pathinfo($ url)を呼び出してファイル名を取得できます。
gradbot 2008年

18
この質問はIISに関するものであり、PHP全般に関するものではないことに注意してください。Apacheでは$ _SERVER ['REQUEST_URI']を使用します。
のMichałTatarynowicz

@Pies確かに$ _SERVER ['REQUEST_URI']は進むべき道です...しかし、どのようにしてURIの特定の部分を取得することができます。たとえば、私はこのURIを持っています:/Appointments/Administrator/events.php/219 ... /events.php/の後に番号を取得する方法
Dimitris Papageorgiou

回答:


135

多分、あなたはIISの下にいるので、

$_SERVER['PATH_INFO']

説明に使用したURLに基​​づく、あなたが望むものです。

Apacheの場合はを使用します$_SERVER['REQUEST_URI']


こんにちはこれを使用して、次のエラーを受け取りますか? Notice: Undefined index: PATH_INFO in /home/tdpk/public_html/system/config.php on line 14
2010年

6
おっと、drat-この質問がIISに関するものであることに気づき、私は使用しています。反対投票して申し訳ありません。
ジェイソンS

63
$pageURL = (@$_SERVER["HTTPS"] == "on") ? "https://" : "http://";
if ($_SERVER["SERVER_PORT"] != "80")
{
    $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} 
else 
{
    $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;

11
OPはIISを明確に述べている-REQUEST_URIはIISでは使用できません
Tom Auger

1
絶対にPHPで行う必要がない限り、マジッククォートを使用しないでください。
ケース

2
@TomAugerタイムラインを見る必要があります。OPは、質問に答えてからずっと後に追加されました。元の質問は、回答する約1年前に行われました。
タイラーカーター、

7
@スタン、ダブルスよりシングルスを使用することには、正味のパフォーマンス上の利点はありません。なし、nadda、zip、ゼロ。これは、PHP3時代の古い妻の物語です。コンテンツに対してこのような些細なマングリングを実行しないでください。
Charles

36

Apacheの場合:

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


Hermanがコメントした ようにのHTTP_HOST代わりに使用することもできSERVER_NAMEます。詳細については、この関連質問を参照してください。つまり、どちらを使用しても問題ないでしょう。これが「ホスト」バージョンです。

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


パラノイドについて/なぜそれが重要か

一般的に、私はセットServerNameではVirtualHost、私がしたいので、それがあることを正規のウェブサイトのフォーム。$_SERVER['HTTP_HOST']リクエストヘッダに基づいて設定されています。サーバーがそのIPアドレスの一部またはすべてのドメイン名に応答する場合、ユーザーがヘッダーを偽装するか、さらに悪いことに、誰かがDNSレコードをあなたのIPアドレスにポイントし、サーバー/ウェブサイトが動的なウェブサイトを提供する可能性があります誤ったURLに基​​づいて作成されたリンク。後者の方法を使用する場合は、次のように、提供するドメインを適用vhostするように.htaccessルールを設定または設定する必要があります。

RewriteEngine On
RewriteCond %{HTTP_HOST} !(^stackoverflow.com*)$
RewriteRule (.*) https://stackoverflow.com/$1 [R=301,L]
#sometimes u may need to omit this slash ^ depending on your server

お役に立てば幸いです。この回答の本当のポイントは、Apacheを使用して完全なURLを取得する方法を検索するときに、ここにたどり着いた人々にコードの最初の行を提供することでした:)


2
これはの$_SERVER['HTTP_HOST']代わりに使用する必要があります$_SERVER['SERVER_NAME']。仮想ホストの設定がある場合、SERVER_NAMEはその名前を表示します。*.example.com有効ではないようなものである可能性があります。
Herman J. Radtke III


9

このクラスを使用して、URLを機能させます。

class VirtualDirectory
{
    var $protocol;
    var $site;
    var $thisfile;
    var $real_directories;
    var $num_of_real_directories;
    var $virtual_directories = array();
    var $num_of_virtual_directories = array();
    var $baseURL;
    var $thisURL;

    function VirtualDirectory()
    {
        $this->protocol = $_SERVER['HTTPS'] == 'on' ? 'https' : 'http';
        $this->site = $this->protocol . '://' . $_SERVER['HTTP_HOST'];
        $this->thisfile = basename($_SERVER['SCRIPT_FILENAME']);
        $this->real_directories = $this->cleanUp(explode("/", str_replace($this->thisfile, "", $_SERVER['PHP_SELF'])));
        $this->num_of_real_directories = count($this->real_directories);
        $this->virtual_directories = array_diff($this->cleanUp(explode("/", str_replace($this->thisfile, "", $_SERVER['REQUEST_URI']))),$this->real_directories);
        $this->num_of_virtual_directories = count($this->virtual_directories);
        $this->baseURL = $this->site . "/" . implode("/", $this->real_directories) . "/";
        $this->thisURL = $this->baseURL . implode("/", $this->virtual_directories) . "/";
    }

    function cleanUp($array)
    {
        $cleaned_array = array();
        foreach($array as $key => $value)
        {
            $qpos = strpos($value, "?");
            if($qpos !== false)
            {
                break;
            }
            if($key != "" && $value != "")
            {
                $cleaned_array[] = $value;
            }
        }
        return $cleaned_array;
    }
}

$virdir = new VirtualDirectory();
echo $virdir->thisURL;

10
これはちょっとやりすぎではないですか?
s3v3n

7

追加:

function my_url(){
    $url = (!empty($_SERVER['HTTPS'])) ?
               "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] :
               "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
    echo $url;
}

次に、my_url関数を呼び出します。


5

次の関数を使用して、現在の完全なURLを取得します。これはIISとApacheで動作するはずです。

function get_current_url() {

  $protocol = 'http';
  if ($_SERVER['SERVER_PORT'] == 443 || (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')) {
    $protocol .= 's';
    $protocol_port = $_SERVER['SERVER_PORT'];
  } else {
    $protocol_port = 80;
  }

  $host = $_SERVER['HTTP_HOST'];
  $port = $_SERVER['SERVER_PORT'];
  $request = $_SERVER['PHP_SELF'];
  $query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';

  $toret = $protocol . '://' . $host . ($port == $protocol_port ? '' : ':' . $port) . $request . (empty($query) ? '' : '?' . $query);

  return $toret;
}

CGIベースのApacheまたはIISを使用していない場合、argvは機能しません。上記のコードを(CGIモードではなく)通常モードのApache2で試しましたが、$ _ SERVER ['arv'] [0]がインデックスではないためエラーが発生しました。また、完全なPHPエラー報告をオンにしており、これらのエラーは通知エラーでした。
Volomike

チャームのように機能し、クエリ文字列パラメーターのエラーを防ぐために少し更新するだけ$query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';です:。これを含めるように回答を更新しました。
Zuul

4

REQUEST_URIはApacheによって設定されるため、IISでは取得できません。$ _SERVERでvar_dumpまたはprint_rを実行して、使用できる値がそこに存在することを確認してください。


3

URLのポストタイトル部分はindex.phpファイルの後にあります。これは、mod_rewriteを使用せずにわかりやすいURLを提供する一般的な方法です。したがって、実際にはポストタイトルはクエリ文字列の一部なので、$ _ SERVER ['QUERY_STRING']を使用して取得できます。


2

使用しているPHPページの上部にある次の行を使用します$_SERVER['REQUEST_URI']。これで問題が解決します。

$_SERVER['REQUEST_URI'] = $_SERVER['PHP_SELF'] . '?' . $_SERVER['argv'][0];

1

ああ、スニペットの楽しさ!

if (!function_exists('base_url')) {
    function base_url($atRoot=FALSE, $atCore=FALSE, $parse=FALSE){
        if (isset($_SERVER['HTTP_HOST'])) {
            $http = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';
            $hostname = $_SERVER['HTTP_HOST'];
            $dir =  str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);

            $core = preg_split('@/@', str_replace($_SERVER['DOCUMENT_ROOT'], '', realpath(dirname(__FILE__))), NULL, PREG_SPLIT_NO_EMPTY);
            $core = $core[0];

            $tmplt = $atRoot ? ($atCore ? "%s://%s/%s/" : "%s://%s/") : ($atCore ? "%s://%s/%s/" : "%s://%s%s");
            $end = $atRoot ? ($atCore ? $core : $hostname) : ($atCore ? $core : $dir);
            $base_url = sprintf( $tmplt, $http, $hostname, $end );
        }
        else $base_url = 'http://localhost/';

        if ($parse) {
            $base_url = parse_url($base_url);
            if (isset($base_url['path'])) if ($base_url['path'] == '/') $base_url['path'] = '';
        }

        return $base_url;
    }
}

次のような美しいリターンがあります。

// A URL like http://stackoverflow.com/questions/189113/how-do-i-get-current-page-full-url-in-php-on-a-windows-iis-server:

echo base_url();    // Will produce something like: http://stackoverflow.com/questions/189113/
echo base_url(TRUE);    // Will produce something like: http://stackoverflow.com/
echo base_url(TRUE, TRUE); || echo base_url(NULL, TRUE); //Will produce something like: http://stackoverflow.com/questions/

// And finally:
echo base_url(NULL, NULL, TRUE);
// Will produce something like:
//      array(3) {
//          ["scheme"]=>
//          string(4) "http"
//          ["host"]=>
//          string(12) "stackoverflow.com"
//          ["path"]=>
//          string(35) "/questions/189113/"
//      }

0

誰もがhttp_build_urlを忘れましたか?

http_build_url($_SERVER['REQUEST_URI']);

パラメータが渡されない場合http_build_urlは、現在のURLが自動的に想定されます。REQUEST_URIGETパラメータを含めるために必要であるように見えますが、含まれることも期待しています。

上記の例は完全なURLを返します。


1
これにはpecl_httpが必要です。
Omar Abid 2013年

@OmarAbid私はそれをお勧めします。:-)
Gajus 2013年

私はあなたの立場を理解しています。ただし、制御できないさまざまなプラットフォームで使用されるスクリプトを作成する場合は、かなり標準的なものを選択する必要があります。
Omar Abid 2013年

1
ライブラリを構築する場合、要件を定義するのはあなた次第です。元の質問はそのようなシナリオをまったく扱っていません。したがって、すべての選択肢に名前を付けることは理にかなっています。
Gajus 2013年

0

次のコードを使用して、正しい結果が得られています...

<?php
    function currentPageURL() {
        $curpageURL = 'http';
        if ($_SERVER["HTTPS"] == "on") {
            $curpageURL.= "s";
        }
        $curpageURL.= "://";
        if ($_SERVER["SERVER_PORT"] != "80") {
            $curpageURL.= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
        } 
        else {
            $curpageURL.= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
        }
        return $curpageURL;
    }
    echo currentPageURL();
?>

正常に動作しているHTTPSがない場合は、その行を削除する必要があります。

0

私のapacheサーバーでは、これはあなたが探している正確な形式で完全なURLを私に与えます:

$_SERVER["SCRIPT_URI"]

0

リバースプロキシのサポート!

もう少し堅牢なもの。これは、5.3それ以上でのみ機能します。

/*
 * Compatibility with multiple host headers.
 * Support of "Reverse Proxy" configurations.
 *
 * Michael Jett <mjett@mitre.org>
 */

function base_url() {

    $protocol = @$_SERVER['HTTP_X_FORWARDED_PROTO'] 
              ?: @$_SERVER['REQUEST_SCHEME']
              ?: ((isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") ? "https" : "http");

    $port = @intval($_SERVER['HTTP_X_FORWARDED_PORT'])
          ?: @intval($_SERVER["SERVER_PORT"])
          ?: (($protocol === 'https') ? 443 : 80);

    $host = @explode(":", $_SERVER['HTTP_HOST'])[0]
          ?: @$_SERVER['SERVER_NAME']
          ?: @$_SERVER['SERVER_ADDR'];

    // Don't include port if it's 80 or 443 and the protocol matches
    $port = ($protocol === 'https' && $port === 443) || ($protocol === 'http' && $port === 80) ? '' : ':' . $port;

    return sprintf('%s://%s%s/%s', $protocol, $host, $port, @trim(reset(explode("?", $_SERVER['REQUEST_URI'])), '/'));
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.