8

(便利な)変数を受け取るポータブルな方法を探しています。$_SERVER['PATH_INFO']

しばらく読んだ後、PATH_INFOCGI/1.1 に由来することが判明し、すべての構成に常に存在するとは限りません。

その変数を取得するための最良の(主にセキュリティ上の)方法は何ですか-手動で抽出することは別として(セキュリティ上の懸念)。

4

6 に答える 6

11

そうですね$_SERVER、スーパーグローバル キーを使用せずに別の方法で特定することはPATH_INFO不可能だと (ほぼ) 確信しています

  • 「PHP_SELF」
  • 'クエリ文字列'
  • 「SCRIPT_FILENAME」
  • 「PATH_TRANSLATED」
  • 「SCRIPT_NAME」
  • 「REQUEST_URI」
  • 'PATH_INFO'
  • 「ORIG_PATH_INFO」

最後の 2 つは明らかに無視する必要があります。今、私たちは(事実についてこれを知りません。あなたがそう言ったので、私はただ推測しています)あなたが提供したリンク( BTWはオフラインATMです)に存在するすべてのキーをフィルタリングする必要があります。これにより、次のキーが残ります:

  • 「PHP_SELF」
  • 「SCRIPT_FILENAME」
  • 「REQUEST_URI」

アンソニーの回答へのコメントについて:

あなたは今、変数をジャグリングしているだけです。 SCRIPT_FILENAMEは CGI 仕様の一部です。が利用できない場合 PATH_INFOは利用できません。に関しては REQUEST_URI、Apache の mod_rewrite 固有です。– リラヌナ

CGI として PHP 5.3.0 を使用して LightTPD/1.4.20-1 (Win32) をcgi.fix_pathinfo = 1$_SERVER['REQUEST_URI']実行しており、非常に利用可能です。また、誰も使用していなかった時代に同じ変数を使用していたことを覚えているmod_rewriteので、私の正直な謙虚な推測は次のとおりです。この点であなたは明らかに間違っています。キーに関しては、SCRIPT_FILENAMEその 1 つの ATM をテストできません。それでも、目を閉じてあなたが正しいと信じている場合、残る変数は 1 つだけです。

  • 「PHP_SELF」

私はここで厳しいことをしようとしているわけではありません (そして、もっと多くの解決策があると今でも信じています) が、PHP_SELFあなたが私たちに取り組んでほしい唯一の鍵である場合 (それ自体に課せられたものがないことを前提PHP_SELFとしています) 残っている解決策は 1 つだけです:

function PATH_INFO()
{
 if (array_key_exists('PATH_INFO', $_SERVER) === true)
 {
  return $_SERVER['PATH_INFO'];
 }

 $whatToUse = basename(__FILE__); // see below

 return substr($_SERVER['PHP_SELF'], strpos($_SERVER['PHP_SELF'], $whatToUse) + strlen($whatToUse));
}

この関数は機能するはずですが、要求された PHP スクリプトへのパスではなく、定数が宣言されているファイルへのパスを返すため、定数__FILE____FILE__使用すると問題が発生する可能性があります。またはに置き換えて'SCRIPT_FILENAME'ください。自分の言っていることを本当に信じている場合は、を使用し'.php'てください。

を使用しない理由については、こちらPHP_SELFもお読みください。

これでうまくいかない場合は、申し訳ありませんが、他の方法を考えます。

編集 - あなたのためのいくつかのより多くの読書:

于 2009-12-16T17:09:53.700 に答える
2

これは、別の方法で「path_info」を取得するためのトリックだと思います。

$path_info = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']);

たとえば、次のような URL へのアクセス: http://somehost.com/index.php/some/path/hereの値は次の$path_infoようになります。"/some/path/here"

WindowsおよびLinuxで実行されているさまざまなApacheサーバーで機能しましたが、「安全」で「ポータブル」であるかどうかは100%確信が持てません。明らかに「すべて」のサーバー構成でテストしていませんが、機能しているようです...

于 2011-04-11T17:25:06.717 に答える
1
function getPathInfo() {
    if (isset($_SERVER['PATH_INFO'])) {
        return $_SERVER['PATH_INFO'];
    }  
    $scriptname = preg_quote($_SERVER["SCRIPT_NAME"], '/');
    $pathinfo = preg_replace("/^$scriptname/", "", $_SERVER["PHP_SELF"]);
    return $pathinfo;
}

編集:SCRIPT_NAMEなしで、DOCUMENT_ROOTがある(または自分で定義/発見できる)と仮定し、SCRIPT_FILENAMEがあると仮定すると、次のようになります。

function getPathInfo() {
    if (isset($_SERVER['PATH_INFO'])) {
        return $_SERVER['PATH_INFO'];
    }  
    $docroot = preg_quote($_SERVER["DOCUMENT_ROOT"], "/");
    $scriptname = preg_replace("/^$docroot/", "", $_SERVER["SCRIPT_FILENAME"]);
    $scriptname = preg_quote($scriptname, "/");
    $pathinfo = preg_replace("/^$scriptname/", "", $_SERVER["PHP_SELF"]);
    return $pathinfo;
}

また、@ Anthony (コメントする担当者が不足しています。申し訳ありません): str_replace() を使用すると、文字列のどこにでも一致します。動作が保証されているわけではありません。最初に一致させるだけです。また、SCRIPT_NAME を決定するために (strrpos を介して) 1 つのスラッシュ バックのみを使用する方法は、スクリプトがルートの下にある場合にのみ機能します。

于 2009-12-15T05:02:12.323 に答える
1

「ポータブル」と「安全」の定義によります。

私が理解したかどうか見てみましょう:

1) CLI には興味がない:

  • あなたはPHP/CGIについて言及しました
  • PATH_INFO は URL の一部です。そのため、スクリプトが URL から (つまり、通常はブラウザによって要求される HTTP 接続から) アクセスされる場合にのみ、PATH_INFO について説明するのが理にかなっています。

2) すべての OS + HTTP サーバー + PHP の組み合わせに PATH_INFO が必要です。

  • OSはWindows、Linuxなど
  • HTTP サーバーは、Apache 1、Apache 2、NginX、Lighttpd などです。
  • PHP は、バージョン 4、5、6、または任意のバージョンである可能性があります

うーん... $_SERVER配列のPHP_INFOは、上記のソフトウェアに応じて、特定の条件下でのみ実行中のスクリプトにPHPによって提供されます。常に利用できるわけではありません。同じことが $_SERVER 配列全体にも当てはまります!

要するに、「$_SERVER はサーバーに依存する」...そのため、移植可能なソリューションは $_SERVER でリレーできません... (一例を挙げると、NginX で PHP/CGI $_SERVER 変数を設定するためのチュートリアルがあります。 kbeezie.com/view/php-self-path-nginx/ の HTTP サーバー)

3) 上記の内容にもかかわらず、リクエストされた完全な URLを何らかの形で文字列として利用できる場合、正規表現やその他の PHP 文字列関数を安全に適用することで、そこから PATH_INFO を取得できることに注意してください (検証も有効です)。入力文字列を有効な URI として)。

そのため、URL 文字列があれば... はい、それから PATH_INFO を決定するための移植可能で安全な方法があります。


現在、明確で的を絞った実装上の問題が 2 つあります。

  1. URL を取得するにはどうすればよいですか?
  2. URL から PATH_INFO を取得する方法は?

いくつかの可能性のうち、可能なアプローチは次のとおりです。

URL を取得するにはどうすればよいですか?

1) 各 HTTP サーバー + OS + PHP バージョンの組み合わせに関する深く包括的な知識を使用して、$_SERVER 配列から URL を取得する可能性を確認して試してください ('PHP_SELF'、'QUERY_STRING'、'SCRIPT_FILENAME'、'PATH_TRANSLATED' を検証します)。 、「SCRIPT_NAME」、「REQUEST_URI」、「PATH_INFO」、「ORIG_PATH_INFO」、「HTTP_HOST」、「DOCUMENT_ROOT」など)

2) 前のステップが失敗した場合、PHP スクリプトが「document.URL」情報を返す JavaScript コードを返すようにします。(移植性の問題はクライアント側に移されました。)

URL から PATH_INFO を取得する方法は?

ここにリンクされているこのコードはこれを行います。

これは私の謙虚な意見であり、問​​題に対するアプローチです。

どう思いますか?

于 2010-05-29T12:45:41.630 に答える
0

投稿する前にコメントやリンクを見ていませんでした。上記のページが CGI 派生変数として提供するものに基づいて、次のように動作する可能性があります。

function getPathInfo() {
    if (isset($_SERVER['PATH_INFO'])) {
        return $_SERVER['PATH_INFO'];
    }  

    $script_filename = $_SERVER["SCRIPT_FILENAME"];
    $script_name_start = strrpos($script_filename, "/");
    $script_name = substr($script_filename, $script_name_start);

    //With the above you should have the plain file name of script without path        

    $script_uri = $_SERVER["REQUEST_URI"];
    $script_name_length = strlen($script_name);
    $path_start = $script_name_length + strpos($script_name, $script_uri);

    //You now have the position of where the script name ends in REQUEST_URI

    $pathinfo = substr($script_uri, $path_start);
    return $pathinfo;
}
于 2009-12-15T05:32:29.413 に答える
-1

あなたは試すことができます

$_ENV['PATH_INFO']; or
getenv('PATH_INFO']; 
于 2009-12-10T21:17:50.550 に答える