(便利な)変数を受け取るポータブルな方法を探しています。$_SERVER['PATH_INFO']
しばらく読んだ後、PATH_INFO
CGI/1.1 に由来することが判明し、すべての構成に常に存在するとは限りません。
その変数を取得するための最良の(主にセキュリティ上の)方法は何ですか-手動で抽出することは別として(セキュリティ上の懸念)。
そうですね$_SERVER
、スーパーグローバル キーを使用せずに別の方法で特定することはPATH_INFO
不可能だと (ほぼ) 確信しています。
最後の 2 つは明らかに無視する必要があります。今、私たちは(事実についてこれを知りません。あなたがそう言ったので、私はただ推測しています)あなたが提供したリンク( BTWはオフラインATMです)に存在するすべてのキーをフィルタリングする必要があります。これにより、次のキーが残ります:
アンソニーの回答へのコメントについて:
あなたは今、変数をジャグリングしているだけです。
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
としています) 残っている解決策は 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
もお読みください。
これでうまくいかない場合は、申し訳ありませんが、他の方法を考えます。
編集 - あなたのためのいくつかのより多くの読書:
REQUEST_URI
Apache 固有であると言い続けるのですか?)PHP_SELF
対PATH_INFO
対SCRIPT_NAME
対REQUEST_URI
これは、別の方法で「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%確信が持てません。明らかに「すべて」のサーバー構成でテストしていませんが、機能しているようです...
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 つのスラッシュ バックのみを使用する方法は、スクリプトがルートの下にある場合にのみ機能します。
「ポータブル」と「安全」の定義によります。
私が理解したかどうか見てみましょう:
1) CLI には興味がない:
2) すべての OS + HTTP サーバー + PHP の組み合わせに PATH_INFO が必要です。
うーん... $_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) 各 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 コードを返すようにします。(移植性の問題はクライアント側に移されました。)
これは私の謙虚な意見であり、問題に対するアプローチです。
どう思いますか?
投稿する前にコメントやリンクを見ていませんでした。上記のページが 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;
}
あなたは試すことができます
$_ENV['PATH_INFO']; or
getenv('PATH_INFO'];