@SilentChris at gmail dot com - I'm seeing the same thing but I'm starting to believe the issue is not PHP but Apache. It looks like Apache's rewrite module is double encoding strings with a '%' sign if they are followed by two or more other characters. So
%25 translates correctly to '%'
%25b translates correctly to '%b'
%25ba translates incorrectly to � which when itself is run through urlencode translates to '%BA'.
Further letters translate correctly.
%25bac produces '�c', etc.
It only appears to happen on the first instance of %25 because further items are translated correctly.
定義済の変数
PHP には定義済みの定数が多く用意されており、すべてのスクリプトで使用することができます。 外部から来る変数 や組み込みの環境変数、直近のエラーメッセージや最後に取得したヘッダなどのあらゆる内容が取得できます。
関連情報については、FAQ の "register_globals の影響は?" を参照ください。
スーパーグローバル
スーパーグローバル — すべてのスコープで使用できる組み込みの変数
説明
PHP の定義済み変数の中には "スーパーグローバル" というものがあります。 これは、スクリプト全体を通してすべてのスコープで使用可能な変数のことです。 関数やメソッドの内部からアクセスする際にも global $variable; などとする必要はありません。
スーパーグローバルには次のようなものがあります。
- $GLOBALS
- $_SERVER
- $_GET
- $_POST
- $_FILES
- $_COOKIE
- $_SESSION
- $_REQUEST
- $_ENV
変更履歴
| バージョン | 説明 |
|---|---|
| 4.1.0 | スーパーグローバルが PHP に導入されました。 |
注意
注意: 使用できる変数
デフォルトでは、すべてのスーパーグローバルが使用可能です。 ただし、それに影響を与える設定項目もあります。詳細は variables_order のドキュメントを参照ください。
注意: register_globals の扱い
非推奨の register_globals ディレクティブが on に設定されている場合は、 内部の変数もスクリプトのグローバルスコープで使用できるようになります。 たとえば $_POST['foo'] は $foo という名前でも使えるようになるということです。
関連情報については、FAQ の "register_globals の影響は?" を参照ください。
注意: 可変変数
スーパーグローバルは、関数やクラスメソッドの中の 可変変数 として使用することはできません。
$GLOBALS
スーパーグローバル -- $GLOBALS — グローバルスコープで使用可能なすべての変数への参照
説明
スクリプトのグローバルスコープに現在定義されているすべての変数への参照を含む連想配列です。 変数名が配列のキーとなります。
例
例1 $GLOBALS の例
<?php
function test() {
$foo = "local variable";
echo '$foo in global scope: ' . $GLOBALS["foo"] . "\n";
echo '$foo in current scope: ' . $foo . "\n";
}
$foo = "Example content";
test();
?>
上の例の出力は、たとえば 以下のようになります。
$foo in global scope: Example content $foo in current scope: local variable
注意
注意: これは 'スーパーグローバル' あるいは自動グローバル変数と呼ばれるものです。 スクリプト全体を通してすべてのスコープで使用することができます。 関数やメソッドの内部で使用する場合にも global $variable; とする必要はありません。
注意: 変数の可用性
他のスーパーグローバル とは異なり、$GLOBALS は PHP で常に使用可能です。
$_SERVER
$HTTP_SERVER_VARS [非推奨]
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] — サーバ情報および実行時の環境情報
説明
$_SERVER は、ヘッダ、パス、スクリプトの位置のような 情報を有する配列です。この配列のエントリは、Web サーバにより 生成されます。全ての Web サーバがこれら全てを提供する保障はありません。 サーバは、これらのいくつかを省略したり、この一覧にない他のものを 定義する可能性があります。これらの変数の多くは、 » CGI 1.1 specification で定義されています。したがって、これらについては定義されていることを 期待することができます。
$HTTP_SERVER_VARS の最初の情報は同じですが、 これはスーパーグローバルではありません (HTTP_SERVER_VARS と $_SERVER は異なる変数であり、 PHP は異なる変数として処理を行うことに注意してください)。
以下の各要素のいくつかは $_SERVER に現れない可能性があります。PHP をコマンドラインで実行している場合には、 使用できるものは僅かであることに注意してください。
- 'PHP_SELF'
- 現在実行しているスクリプトのファイル名です。 ドキュメントルートから取得されます。 例えば、http://example.com/test.php/foo.bar というアドレス上にあるスクリプトでは $_SERVER['PHP_SELF'] は /test.php/foo.bar となります。 __FILE__ 定数 には、カレント(すなわち読み込まれた)ファイルのパスとファイル名が含まれます。 PHP がコマンドラインから実行される場合、PHP 4.3.0 以降、 この変数にはスクリプト名が含まれます。これより前のバージョンでは、 この変数は使用できません。
- 'argv'
- スクリプトに渡された引数の配列です。スクリプトがコマンドラインから 実行された場合、C 言語スタイルでコマンドライン引数に アクセスすることができます。GET メソッドを通してコールされた場合には 検索引数が格納されます。
- 'argc'
- スクリプトに渡されたコマンドライン引数の数 (コマンドラインから実行した場合) です。
- 'GATEWAY_INTERFACE'
- サーバが使用している CGI のバージョンです。 例 'CGI/1.1'
- 'SERVER_ADDR'
- 現在のスクリプトが実行されているサーバの IP アドレスです。
- 'SERVER_NAME'
- 現在のスクリプトが実行されているサーバのホスト名です。 スクリプトがバーチャルホスト上で実行されている場合は そのバーチャルホスト名となります。
- 'SERVER_SOFTWARE'
- レスポンスヘッダ上に書かれている、 サーバの認識文字列です。
- 'SERVER_PROTOCOL'
- ページがリクエストされた際のプロトコル名とバージョンです。 例.'HTTP/1.0'
- 'REQUEST_METHOD'
-
ページにアクセスする際に使用されたリクエストのメソッド名です。
'GET', 'HEAD',
'POST', 'PUT' など。
注意: リクエストのメソッドが HEAD だった場合、 PHP スクリプトはヘッダを送信した後(言い換えれば、 出力バッファリングを行わずに全出力を処理した後)に終了します。
- 'REQUEST_TIME'
- リクエストの開始時のタイムスタンプ。PHP 5.1.0 以降で利用可能。
- 'QUERY_STRING'
- ページがアクセスされた際にもし検索引数があればそれが格納されます。
- 'DOCUMENT_ROOT'
- 現在実行されているスクリプトが存在するドキュメントルート ディレクトリです。サーバのコンフィグレーションファイルで 定義されています。
- 'HTTP_ACCEPT'
- 現在のリクエストの Accept: ヘッダがもしあれば その内容。
- 'HTTP_ACCEPT_CHARSET'
- 現在のリクエストの Accept-Charset: ヘッダが もしあればその内容。例: 'iso-8859-1,*,utf-8'
- 'HTTP_ACCEPT_ENCODING'
- 現在のリクエストに Accept-Encoding: ヘッダが もしあればその内容。例: 'gzip'
- 'HTTP_ACCEPT_LANGUAGE'
- 現在のリクエストに Accept-Language: ヘッダが もしあればその内容。例: 'en'
- 'HTTP_CONNECTION'
- 現在のリクエストに Connection: ヘッダが もしあればその内容。例: 'Keep-Alive'
- 'HTTP_HOST'
- 現在のリクエストに Host: ヘッダが もしあればその内容。
- 'HTTP_REFERER'
- 現在のページに遷移する前にユーザエージェントが参照していた ページのアドレス(もしあれば)。これはユーザエージェントに よってセットされます。全てのユーザエージェントが これをセットしているわけではなく、また、HTTP_REFERER を変更する機能を持つものもああります。 要するに、信頼するべきものではありません。
- 'HTTP_USER_AGENT'
- 現在のリクエストに User-Agent: ヘッダが もしあればその内容。ページにアクセスしてきているユーザエージェント のしるしの文字列です。典型的な例は、 Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586)。たとえば、 get_browser() でこの値を使って ページの出力をそのブラウザにあわせたものにすることも できるでしょう。
- 'HTTPS'
- スクリプトが HTTPS プロトコルを通じて実行されている場合に 空でない値が設定されます。 ISAPI を IIS で使用している場合は、HTTPS プロトコルを通さないでリクエストが行われたときの値は off となることに注意しましょう。
- 'REMOTE_ADDR'
- 現在ページをみているユーザの IP アドレス。
- 'REMOTE_HOST'
-
現在のページにアクセスしているホスト名。DNS の逆引き検索は
ユーザの REMOTE_ADDR に基づいています。
注意: Web サーバがこの値を生成できるように設定されている必要があります。 例えば Apache の場合 HostnameLookups On が httpd.conf に設定されていなければこの値は生成されません。 gethostbyaddr() もご覧ください。
- 'REMOTE_PORT'
- ユーザのマシンから Web サーバへの通信に使用されているポート番号
- 'SCRIPT_FILENAME'
-
現在実行されているスクリプトの絶対パス
注意: file.php あるいは ../file.php のような相対パスを指定して CLI でスクリプトが実行されている場合、 $_SERVER['SCRIPT_FILENAME'] には ユーザが指定した相対パスが含まれます。
- 'SERVER_ADMIN'
- Web サーバの設定ファイルの SERVER_ADMIN (Apache の場合)ディレクティブ にセットされている値。スクリプトがバーチャルホスト上で 実行されている場合、バーチャルホストに対して値が定義されます。
- 'SERVER_PORT'
- Web サーバの通信ポートとして使用されているポート番号。デフォルトでは '80' ですが、例えば SSL を使用している場合は セキュア HTTP ポートとして設定されている値に変わります。
- 'SERVER_SIGNATURE'
- サーバ上で生成されたページに追加される、 サーバのバージョン名とバーチャルホスト名の文字列。 Web サーバの設定で有効になっていることが必要です。
- 'PATH_TRANSLATED'
-
バーチャルからリアルへのマッピングがなされた後の、
現在のスクリプトのファイルシステム上(ドキュメントルートではなく)
でのパス。
注意: PHP 4.3.2 以降、PATH_TRANSLATED は、 Apache 2 SAPI において暗黙のうちに設定されなく なりました。一方、Apache 1 では、この値が Apache により設定されない場合、 SCRIPT_FILENAME と同じ値に設定されます。 この変更は、PATH_TRANSLATED は PATH_INFO が定義されている場合のみ 存在するべきであるという CGI の規約を満たすために 行われました。 Apache 2 ユーザは、PATH_INFO を定義するために httpd.conf の中で AcceptPathInfo = On を使用することが可能です。
- 'SCRIPT_NAME'
- 現在のスクリプトのパス。 スクリプト自身のページを指定するのに有用です。 __FILE__ 定数には、カレント(すなわち読み込まれた)ファイルのパスとファイル名が 含まれます。
- 'REQUEST_URI'
- ページにアクセスするために指定された URI。例えば、 '/index.html'
- 'PHP_AUTH_DIGEST'
- PHP を Apache のモジュールとして実行し、HTTP ダイジェスト認証を 行っている場合、クライアントから送られた 'Authorization' ヘッダの 内容が設定されます(適切な認証処理を行うために利用します)。
- 'PHP_AUTH_USER'
- PHP を Apache または IIS(PHP 5 での ISAPI)のモジュールとして 実行している場合に、HTTP 認証しているときにそのユーザ名がセットされます。
- 'PHP_AUTH_PW'
- PHP を Apache または IIS(PHP 5 での ISAPI)のモジュールとして 実行している場合に、HTTP 認証しているときにそのユーザの パスワードがセットされます。
- 'AUTH_TYPE'
- PHP を Apache のモジュールとして実行している場合に、 HTTP 認証しているときにその認証形式がセットされます。
変更履歴
| バージョン | 説明 |
|---|---|
| 4.1.0 | $_SERVER が導入され、 $HTTP_SERVER_VARS は非推奨となりました。 |
例
例2 $_SERVER の例
<?php
echo $_SERVER['SERVER_NAME'];
?>
上の例の出力は、たとえば 以下のようになります。
www.example.com
注意
注意: これは 'スーパーグローバル' あるいは自動グローバル変数と呼ばれるものです。 スクリプト全体を通してすべてのスコープで使用することができます。 関数やメソッドの内部で使用する場合にも global $variable; とする必要はありません。
$_GET
$HTTP_GET_VARS [非推奨]
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] — HTTP GET 変数
説明
HTTP GET メソッドで現在のスクリプトに渡された変数の連想配列です。
$HTTP_GET_VARS は同じ情報を持っていますが、 これはスーパーグローバルではありません (HTTP_GET_VARS と $_GET は違う変数であり、PHPはそれぞれ別に扱います)。
変更履歴
| バージョン | 説明 |
|---|---|
| 4.1.0 | $_GET が導入され、 $HTTP_GET_VARS は非推奨となりました。 |
例
例3 $_GET の例
<?php
echo 'Hello ' . htmlspecialchars($_GET["name"]) . '!';
?>
ユーザが http://example.com/?name=Hannes と入力したとします。
上の例の出力は、たとえば 以下のようになります。
Hello Hannes!
注意
注意: これは 'スーパーグローバル' あるいは自動グローバル変数と呼ばれるものです。 スクリプト全体を通してすべてのスコープで使用することができます。 関数やメソッドの内部で使用する場合にも global $variable; とする必要はありません。
$_POST
$HTTP_POST_VARS [非推奨]
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] -- $_POST -- $HTTP_POST_VARS [非推奨] — HTTP POST 変数
説明
HTTP POST メソッドで現在のスクリプトに渡された変数の連想配列です。
$HTTP_POST_VARS は同じ情報を持っていますが、 これはスーパーグローバルではありません (HTTP_POST_VARS と $_POST は違う変数であり、PHPはそれぞれ別に扱います)。
変更履歴
| バージョン | 説明 |
|---|---|
| 4.1.0 | $_POST が導入され、 $HTTP_POST_VARS は非推奨となりました。 |
例
例4 $_POST の例
<?php
echo 'Hello ' . htmlspecialchars($_POST["name"]) . '!';
?>
ユーザが name=Hannes と POST したとします。
上の例の出力は、たとえば 以下のようになります。
Hello Hannes!
注意
注意: これは 'スーパーグローバル' あるいは自動グローバル変数と呼ばれるものです。 スクリプト全体を通してすべてのスコープで使用することができます。 関数やメソッドの内部で使用する場合にも global $variable; とする必要はありません。
$_FILES
$HTTP_POST_FILES [非推奨]
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] -- $_POST -- $HTTP_POST_VARS [非推奨] -- $_FILES -- $HTTP_POST_FILES [非推奨] — HTTP ファイルアップロード変数
説明
HTTP POST メソッドで現在のスクリプトにアップロードされた項目の連想配列です。
$HTTP_POST_FILES は同じ情報を持っていますが、 これはスーパーグローバルではありません ($HTTP_POST_FILES と $_FILES は異なる変数であり、PHP はこれらを異なる変数として扱うことに注意してください)。
変更履歴
| バージョン | 説明 |
|---|---|
| 4.1.0 | $_FILES が導入され、 $HTTP_POST_FILES は非推奨となりました。 |
注意
注意: これは 'スーパーグローバル' あるいは自動グローバル変数と呼ばれるものです。 スクリプト全体を通してすべてのスコープで使用することができます。 関数やメソッドの内部で使用する場合にも global $variable; とする必要はありません。
$_REQUEST
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] -- $_POST -- $HTTP_POST_VARS [非推奨] -- $_FILES -- $HTTP_POST_FILES [非推奨] -- $_REQUEST — HTTP リクエスト変数
説明
$_GET、 $_POST そして $_COOKIE の内容をまとめた連想配列です。
変更履歴
| バージョン | 説明 |
|---|---|
| 5.3.0 | request_order が導入されました。 このディレクティブは $_REQUEST の内容に影響を及ぼします。 |
| 4.3.0 | $_FILES の情報が $_REQUEST から削除されました。 |
| 4.1.0 | $_REQUEST が導入されました。 |
注意
注意: これは 'スーパーグローバル' あるいは自動グローバル変数と呼ばれるものです。 スクリプト全体を通してすべてのスコープで使用することができます。 関数やメソッドの内部で使用する場合にも global $variable; とする必要はありません。
注意: コマンドライン で実行する場合、ここには argv や argc の内容は含まれません。これらの内容は $_SERVER 配列に格納されます。
注意: 変数の内容は、GET や POST そして COOKIE といった仕組みで入力されます。 これらは信頼できるとは限りません。この配列内に含まれる変数の値や順序は、 PHP の設定ディレクティブ variables_order で決まります。
$_SESSION
$HTTP_SESSION_VARS [非推奨]
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] -- $_POST -- $HTTP_POST_VARS [非推奨] -- $_FILES -- $HTTP_POST_FILES [非推奨] -- $_REQUEST -- $_SESSION -- $HTTP_SESSION_VARS [非推奨] — セッション変数
説明
現在のスクリプトで使用できるセッション変数を含む連想配列です。 セッション変数の使用法についての詳細は、 セッション関数 のドキュメントを参照ください。
$HTTP_SESSION_VARS は同じ情報を格納していますが、 これはスーパーグローバルではありません ($HTTP_SESSION_VARS と $_SESSION は異なる変数であり、PHP はこれらを異なる変数として扱うことに注意してください)。
変更履歴
| バージョン | 説明 |
|---|---|
| 4.1.0 | $_SESSION が導入され、 $HTTP_SESSION_VARS は非推奨となりました。 |
注意
注意: これは 'スーパーグローバル' あるいは自動グローバル変数と呼ばれるものです。 スクリプト全体を通してすべてのスコープで使用することができます。 関数やメソッドの内部で使用する場合にも global $variable; とする必要はありません。
$_ENV
$HTTP_ENV_VARS [非推奨]
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] -- $_POST -- $HTTP_POST_VARS [非推奨] -- $_FILES -- $HTTP_POST_FILES [非推奨] -- $_REQUEST -- $_SESSION -- $HTTP_SESSION_VARS [非推奨] -- $_ENV -- $HTTP_ENV_VARS [非推奨] — 環境変数
説明
環境変数として現在のスクリプトに渡された変数の連想配列です。
これらの変数は PHP パーサが実行されている環境から PHP のグローバル名前空間に取り込まれます。 その多くは、PHP が実行されているシェルに由来するものであり、 システムが違えばシェルも違ってくるため、確定的なリストを 得ることは不可能です。定義されている環境変数のリストについては 使用しているシェルのドキュメントをご覧ください。
CGI 変数を含むその他の環境変数も、 PHP がサーバモジュールとして実行されているか CGI プロセッサとして 実行されているかに関わらずここに含まれます。
$HTTP_ENV_VARS は同じ情報を持っていますが、 これはスーパーグローバルではありません ($HTTP_ENV_VARS と $_ENV は違う変数であり、PHP はそれぞれ別に扱います)。
変更履歴
| バージョン | 説明 |
|---|---|
| 4.1.0 | $_ENV が導入され、 $HTTP_ENV_VARS は非推奨となりました。 |
例
例5 $_ENV の例
<?php
echo 'My username is ' .$_ENV["USER"] . '!';
?>
"bjori" がこのスクリプトを実行したとします。
上の例の出力は、たとえば 以下のようになります。
My username is bjori!
注意
注意: これは 'スーパーグローバル' あるいは自動グローバル変数と呼ばれるものです。 スクリプト全体を通してすべてのスコープで使用することができます。 関数やメソッドの内部で使用する場合にも global $variable; とする必要はありません。
$_COOKIE
$HTTP_COOKIE_VARS [非推奨]
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] -- $_POST -- $HTTP_POST_VARS [非推奨] -- $_FILES -- $HTTP_POST_FILES [非推奨] -- $_REQUEST -- $_SESSION -- $HTTP_SESSION_VARS [非推奨] -- $_ENV -- $HTTP_ENV_VARS [非推奨] -- $_COOKIE -- $HTTP_COOKIE_VARS [非推奨] — HTTP クッキー
説明
現在のスクリプトに HTTP クッキーから渡された変数の連想配列です。
$HTTP_COOKIE_VARS は同じ情報を持っていますが、 これはスーパーグローバルではありません ($HTTP_COOKIE_VARS と $_COOKIE は違う変数であり、PHP はそれぞれ別に扱います)。
変更履歴
| バージョン | 説明 |
|---|---|
| 4.1.0 | $_COOKIE が導入され、 $HTTP_COOKIE_VARS は非推奨となりました。 |
例
例6 $_COOKIE の例
<?php
echo 'Hello ' . htmlspecialchars($_COOKIE["name"]) . '!';
?>
"name" というクッキーが事前に設定されているものとします。
上の例の出力は、たとえば 以下のようになります。
Hello Hannes!
注意
注意: これは 'スーパーグローバル' あるいは自動グローバル変数と呼ばれるものです。 スクリプト全体を通してすべてのスコープで使用することができます。 関数やメソッドの内部で使用する場合にも global $variable; とする必要はありません。
$php_errormsg
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] -- $_POST -- $HTTP_POST_VARS [非推奨] -- $_FILES -- $HTTP_POST_FILES [非推奨] -- $_REQUEST -- $_SESSION -- $HTTP_SESSION_VARS [非推奨] -- $_ENV -- $HTTP_ENV_VARS [非推奨] -- $_COOKIE -- $HTTP_COOKIE_VARS [非推奨] -- $php_errormsg — 直近のエラーメッセージ
説明
$php_errormsg は、PHP によって発せられた 最後のエラーメッセージのテキストを格納する変数です。 エラーが発生したスコープ内、かつ track_errors 設定オプションが オン (デフォルトはオフ) にセットされている場合にのみ有効です。
注意: この変数は、track_errors が php.ini で有効になっている場合にのみ使用可能です。
ユーザ定義のエラーハンドラ が設定されている場合は、$php_erromsg はエラーハンドラが FALSE を返した場合にのみ設定されます。
例
例7 $php_errormsg の例
<?php
@strpos();
echo $php_errormsg;
?>
上の例の出力は、たとえば 以下のようになります。
Wrong parameter count for strpos()
$HTTP_RAW_POST_DATA
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] -- $_POST -- $HTTP_POST_VARS [非推奨] -- $_FILES -- $HTTP_POST_FILES [非推奨] -- $_REQUEST -- $_SESSION -- $HTTP_SESSION_VARS [非推奨] -- $_ENV -- $HTTP_ENV_VARS [非推奨] -- $_COOKIE -- $HTTP_COOKIE_VARS [非推奨] -- $php_errormsg -- $HTTP_RAW_POST_DATA — 生の POST データ
説明
$HTTP_RAW_POST_DATA には生の POST データが格納されます。 always_populate_raw_post_data も参照ください。
$http_response_header
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] -- $_POST -- $HTTP_POST_VARS [非推奨] -- $_FILES -- $HTTP_POST_FILES [非推奨] -- $_REQUEST -- $_SESSION -- $HTTP_SESSION_VARS [非推奨] -- $_ENV -- $HTTP_ENV_VARS [非推奨] -- $_COOKIE -- $HTTP_COOKIE_VARS [非推奨] -- $php_errormsg -- $HTTP_RAW_POST_DATA -- $http_response_header — HTTP レスポンスヘッダ
説明
$http_response_header 配列は get_headers() 関数と似ています。 HTTP ラッパー を使用する際に、$http_response_header に HTTP レスポンスヘッダが格納されます。
例
例8 $http_response_header の例
<?php
file_get_contents("http://example.com");
var_dump($http_response_header);
?>
上の例の出力は、たとえば 以下のようになります。
array(9) { [0]=> string(15) "HTTP/1.1 200 OK" [1]=> string(35) "Date: Sat, 12 Apr 2008 17:30:38 GMT" [2]=> string(29) "Server: Apache/2.2.3 (CentOS)" [3]=> string(44) "Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT" [4]=> string(27) "ETag: "280100-1b6-80bfd280"" [5]=> string(20) "Accept-Ranges: bytes" [6]=> string(19) "Content-Length: 438" [7]=> string(17) "Connection: close" [8]=> string(38) "Content-Type: text/html; charset=UTF-8" }
$argc
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] -- $_POST -- $HTTP_POST_VARS [非推奨] -- $_FILES -- $HTTP_POST_FILES [非推奨] -- $_REQUEST -- $_SESSION -- $HTTP_SESSION_VARS [非推奨] -- $_ENV -- $HTTP_ENV_VARS [非推奨] -- $_COOKIE -- $HTTP_COOKIE_VARS [非推奨] -- $php_errormsg -- $HTTP_RAW_POST_DATA -- $http_response_header -- $argc — スクリプトに渡された引数の数
説明
コマンドラインから実行したときに、 現在のスクリプトに渡された引数の数が含まれます。
注意: スクリプトのファイル名は、常にスクリプトへの引数として渡されます。 したがって、$argc の最小値は 1 です。
注意: この変数は、register_argc_argv が有効になっている場合にのみ使用可能です。
例
例9 $argc の例
<?php
var_dump($argc);
?>
このサンプルを php script.php arg1 arg2 arg3 と実行します。
上の例の出力は、たとえば 以下のようになります。
int(4)
$argv
スーパーグローバル -- $GLOBALS -- $_SERVER -- $HTTP_SERVER_VARS [非推奨] -- $_GET -- $HTTP_GET_VARS [非推奨] -- $_POST -- $HTTP_POST_VARS [非推奨] -- $_FILES -- $HTTP_POST_FILES [非推奨] -- $_REQUEST -- $_SESSION -- $HTTP_SESSION_VARS [非推奨] -- $_ENV -- $HTTP_ENV_VARS [非推奨] -- $_COOKIE -- $HTTP_COOKIE_VARS [非推奨] -- $php_errormsg -- $HTTP_RAW_POST_DATA -- $http_response_header -- $argc -- $argv — スクリプトに渡された引数の配列
説明
コマンドラインから実行したときに、 現在のスクリプトに渡されたすべての引数の配列が含まれます。
注意: 最初の引数は、常に現在のスクリプトのファイル名となります。 したがって、$argv[0] はスクリプトの名前となります。
注意: この変数は、register_argc_argv が有効になっている場合にのみ使用可能です。
例
例10 $argv の例
<?php
var_dump($argv);
?>
このサンプルを php script.php arg1 arg2 arg3 と実行します。
上の例の出力は、たとえば 以下のようになります。
array(4) { [0]=> string(10) "script.php" [1]=> string(4) "arg1" [2]=> string(4) "arg2" [3]=> string(4) "arg3" }
定義済の変数
24-Jun-2008 07:08
31-May-2008 03:05
SETUP: Using PHP 5.2.5 and have magic_quotes_gpc set to "Off" in php.ini (in fact, all the magic_quotes options are set to Off).
It appears that _GET / _POST / _COOKIE are all pre-urldecoding their data. When I call urldecode on any of the variables retrieved from one of these superglobals, it comes back as though it were *double* urldecoded (which could be dangerous).
In my example, I had urlencoded a cookie with the string "%40" in it. I urlencoded that string before caling setrawcookie(). When I got the string back from $_COOKIE on a subsequent request, it already was decoded to show %40.
I have yet to find any specific documentation about whether or not _GET/_POST/_COOKIE are auto-urldecoded, but from experience they appear to be (regardless of php.ini settings).
07-Apr-2008 07:15
When using a php script like a remote function call, I find something like this useful for setting default parameters.
<?php
/**
/* combine _GET _POST _COOKIE variables with provided default values
/* defaults - associative array of default values
/* overwrite - if true, write result to _REQUEST superglobal
/* super_globals - array of super globals to fetch values from
**/
function get_params($defaults = null, $overwrite = false, $super_globals = array('_GET', '_POST', '_COOKIE'))
{
$ret = array();
// fetch values from request
foreach($super_globals as $sg)
foreach($GLOBALS[$sg] as $k=>$v)
$ret[$k] = $v;
// apply defaults for missing parameters
if($defaults) foreach($defaults as $k=>$v)
if(!isset($ret[$k]))
$ret[$k] = $v;
if($overwrite)
$_REQUEST = $ret;
return $ret;
}
// Example: page.php?style=modern
$argv = get_params(array('id'=>42, 'style'=>'medieval'));
// $argv['id'] = 42
// $argv['style'] = 'modern'
?>
19-Feb-2008 01:56
Note the manual entry for PHP_SELF states the following:
"The filename of the currently executing script, relative to the document root. For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar would be /test.php/foo.bar."
However I did some vigorous testing on three different machines and this note is not always true. The results are given below:
Given a URL of http://www.example.com/Info.php/Page/Home
Apache 2.2.4/Win32/PHP 5.2.2/Apache 2.0 Handler
----> PHP_SELF = Info.php/Page/Home
Apache 1.3.37/Unix/PHP 5.2.2/CGI
----> PHP_SELF = Info.php
Apache 1.3.33/Unix/5.1.4/FastCGI
----> PHP_SELF = Info.php
To be completely honest, I am not sure why this is the case; perhaps there is a setting in Apache to modify this option, but in either case take careful consideration of this note.
13-Feb-2008 04:15
I was a little frustrated by the fact that some of the _SERVER variables didn't seem to exist, so I did a bit of Googling and found the answer: many of these variables are supplied by the web server and not all web servers supply the same set of variables.
I found a comparison between Apache v1.3.29 and IIS v5.1 on this page: http://koivi.com/apache-iis-php-server-array.php Useful for those of us doing cross-platform development.
While running experiments with different browsers I noticed some of the HTTP_* variables come and go depending on the browser used, or in the case of Opera by diddling the "user mode" (the widget that lets you look at a page as text only, etc.). For example: in IE and Opera HTTP_KEEP_ALIVE was missing, but was present in Firefox and Mozilla, and when I fiddled with Opera's "user mode" I got somethings called HTTP_TE and HTTP_CACHE_CONTROL.
So, what you get is dependent on the web server AND the browser.
I did see one IIS supplied variable not on that list: REQUEST_TIME, which seems to be in Unix timestamp format.
While researching this I discovered there are plenty of people who have their phpinfo() page visible and indexed on a few search engines. For those who want to dig a bit deeper than that nice web page comparing Apache to IIS, looking at other peoples' phpinfo() pages could be useful. You get the version of PHP plus OS and web server they use, along with all the _SERVER variables. I found the highest percent of signal-to-noise by searching for "phpinfo()" (with the quotes) on Dogpile: http://www.dogpile.com/
13-Dec-2007 06:40
In addition to mfyahya at gmail dot com (2007-06-07 03:33):
If You are working with the Apache module mod_rewrite and want to set some environment vars, the Apache manual says this vars could be accessed in CGI using $ENV{VAR}. In PHP You might want to write $_ENV['VAR'] to get the value of VAR, but You have to access if via $_SERVER, and in some different ways:
1. Example: .htaccess and example.php
RewriteEngine on
RewriteRule ^?var1=([^;]*);var2=([^;]*)$ \
- [E=VAR1:$1,E=VAR2:$2]
<?php echo($_SERVER['VAR1']."\r\n"
.$_SERVER['VAR2']); ?>
2. Example: .htaccess and index.php
RewriteEngine on
RewriteRule ^index\.php$ - [L]
RewriteRule ?var1=([^;]*);var2=([^;]*)$ \
index.php [E=VAR1:$1,E=VAR2:$2]
<?php echo($_SERVER['REDIRECT_VAR1']."\r\n"
.$_SERVER['REDIRECT_VAR2']); ?>
Note: If any RewriteRule matches, an internal redirect than restarts (after the last defined rule, or immediately after the matched rule having a L-flag) checking the entire rule set again. For an internal redirect every defined VAR gets an 'REDIRECT_' prefix, i.e. VAR1 will be REDIRECT_VAR1, VAR2 will be REDIRECT_VAR2.
Of course, You can (additionally) redefine the original VAR:
RewriteEngine on
RewriteRule ^index\.php$ \
- [E=VAR1:%{REDIRECT_VAR1},E=VAR2:%{REDIRECT_VAR2},L]
RewriteRule ?var1=([^;]*);var2=([^;]*)$ \
index.php [E=VAR1:$1,E=VAR2:$2]
With this, You will have $_SERVER['REDIRECT_VAR*'] -and- $_SERVER['VAR*'].
***
The given examples are only for explanation, in any case they are not intended to fit Your needs. The "\<CRLF><SP>" in the .htaccess examples are only for display purpose, they should not occur in a real .htaccess file. The argument separator ';' in links can also be '&', but this may cause some trouble with HTML/XHTML. See the following pages for more information about this issue:
- http://www.w3.org/TR/html4/appendix/notes.html#h-B.2.2
- http://www.w3.org/QA/2005/04/php-session
22-Nov-2007 09:49
SECURITY RISK !
Never ever trust the values that comes from $_SERVER.
HTTP_X_FORWARDED, HTTP_X_FORWARDED_FOR, HTTP_FORWARDED_FOR, HTTP_FORWARDED, etc.. can be spoofed !
To get the ip of user, use only $_SERVER['REMOTE_ADDR'], otherwise the 'ip' of user can be easily changed by sending a HTTP_X_* header, so user can escape a ban or spoof a trusted ip.
Of course this is well know, but I don't see it mentioned in these notes..
If you use the ip only for tracking (not for any security features like banning or allow access to something by ip), you can also use HTTP_X_FORWARDED to get user's ip what are behind proxy.
14-Nov-2007 08:03
In response to mathiasrav's getip() implementation on 28-Jul-2007, it should be noted that it:
- assumes IPv4 addresses only
- returns $_SERVER['REMOTE_ADDR'] for any value of $_SERVER['HTTP_CLIENT_IP'] that matches 127.0.*.*, 192.168.*.* or 10.0.*.*, which is not desirable if you actually WANT the value of HTTP_CLIENT_IP
dlyaza's prior snippet has neither of these problems.
01-Nov-2007 04:59
Note that some headers will be checked for validity (by Apache, I suppose) before showing up in $_SERVER -- If-Modified-Since for example.
<?php
$lastmod = gmdate('D, d M Y H:i:s', filemtime('somefile'));
header("Last-Modified: $lastmod");
?>
This WON'T work, "GMT" is missing. Internet Explorer auto-fixes this by adding GMT, while Firefox resends this data as-is. (So an If-Modified-Since-header is sent, but neither shows up in $_SERVER nor in apache_request_headers()). This would be correct:
<?php
$lastmod = gmdate('D, d M Y H:i:s', filemtime('somefile')) . 'GMT';
header("Last-Modified: $lastmod");
?>
19-Oct-2007 10:39
@White-Gandalf: one can control this behavior by setting:
UseCanonicalName On|Off
in their apache config (at least, on *ix platforms).
On => $_SERVER['SERVER_NAME'] is the ServerName var from either the global server or virtual host, whichever wraps the PHP app closest.
Off => Whatever was in the Host: header sent by the client.
16-Oct-2007 05:01
'SERVER_NAME' does NOT necessarily refer to the name of a virtual host or any other things defined in the apache config.
Instead it simply takes the value of the "Host:" entry of the HTTP-header sent by the client.
At least with apache version 2.2.5 on Windows.
21-Sep-2007 06:45
The headers sent by the browser will be stored in the $_SERVER array -- they will get capitalized and prefixed with HTTP. So a header like "X-Foo-Bar: Baz" will result in <?php $_SERVER['HTTP_X_FOO_BAR'] = 'Baz';?>. This is why you should use isset before using e.g. HTTP_ACCEPT_LANGUAGE, 'cause it may not be set.
The only exception I know from that is HTTP_X_ORIGINAL_URI, which is always set and holds the current URL without querystring. But you can't trust that too because it can be overriden by sending a X-Original-URI header.
05-Aug-2007 07:41
To get the directory of the current script: (I think this is a little more resource-friendly, but then again with all the fast computers available, it does not matter so much...)
<?
// For the script that is running:
$script_directory = substr($_SERVER['SCRIPT_FILENAME'], 0, strrpos($_SERVER['SCRIPT_FILENAME'], '/'));
// If your script is included from another script:
$included_directory = substr(__FILE__, 0, strrpos(__FILE__, '/'));
echo $script_directory . '<br />';
echo $included_directory . '<br />';
?>
If you have a script that only includes the script written above in a directory called 'includer', and I access it from a web browser, this will be what I see:
/path/to/includer/
/path/to/included/
11-Apr-2007 05:37
If you're working with $_GET a lot and need to preserve already set variables in a link for the next page, this function is pretty handy for simplifying the process of generating a new URL:
string setUrlVariables([string var, string value], [varN, valueN], ...)
<?php
function setUrlVariables() {
$arg = array();
$string = "?";
$vars = $_GET;
for ($i = 0; $i < func_num_args(); $i++)
$arg[func_get_arg($i)] = func_get_arg(++$i);
foreach (array_keys($arg) as $key)
$vars[$key] = $arg[$key];
foreach (array_keys($vars) as $key)
if ($vars[$key] != "") $string.= $key . "=" . $vars[$key] . "&";
if (SID != "" && SID != "SID" && $_GET["PHPSESSID"] == "")
$string.= htmlspecialchars(SID) . "&";
return htmlspecialchars(substr($string, 0, -1));
}
?>
You use it like this:
<a href="nextpage.php<?php echo setUrlVariables(); ?>">Link</a>
In this case setUrlVariables() will simply add all the $_GET variables of the current page/URL and even takes care of the PHPSESSID if you use one (and didn't change the default variable name). The above HREF would complete to e.g.:
"nextpage.php?var=21&PHPSESSID=BI89J"
If you supply arguments, do it like this:
<?php echo setUrlVariables("user", "foobar"); ?>
This would complete the HREF to e.g.:
"nextpage.php?user=foobar&var=21&PHPSESSID=BI89J"
Unsetting variables works by supplying an empty value:
<?php echo setUrlVariables("var", ""); ?>
"nextpage.php?user=foobar&PHPSESSID=BI89J"
setUrlVariables() also makes sure it produces "pretty URLs", so it doesn't output any unnecessary garbage. ;)
<?php
session_destroy();
echo setUrlVariables("user", "");
?>
"nextpage.php"
21-Mar-2007 10:22
If you have problems with $_SERVER['HTTPS'], especially if it returns no values at all you should check the results of phpinfo(). It might not be listed at all.
Here is a solution to check and change, if necessary, to ssl/https that will work in all cases:
<?php
if ($_SERVER['SERVER_PORT']!=443) {
$sslport=443; //whatever your ssl port is
$url = "https://". $_SERVER['SERVER_NAME'] . ":" . $sslport . $_SERVER['REQUEST_URI'];
header("Location: $url");
}
?>
Of course, this should be done before any html tag or php echo/print.
24-Jan-2007 09:53
I think it is very important to note that PHP will automatically replace dots ('.') AND spaces (' ') with underscores ('_') in any incoming POST or GET (or REQUEST) variables.
This page notes the dot replacement, but not the space replacement:
http://us2.php.net/manual/en/language.variables.external.php
The reason is that '.' and ' ' are not valid characters to use in a variable name. This is confusing to many people, because most people use the format $_POST['name'] to access these values. In this case, the name is not used as a variable name but as an array index, in which those characters are valid.
However, if the register_globals directive is set, these names must be used as variable names. As of now, PHP converts the names for these variables before inserting them into the external variable arrays, unfortunately - rather than leaving them as they are for the arrays and changing the names only for the variables set by register_globals.
If you want to use:
<input name="title for page3.php" type="text">
The value you will get in your POST array, for isntance would be:
$_POST['title_for_page3_php']
18-Nov-2006 04:22
The *only* way to make Request_URI work as a 100% Apache-Compliant server variable on IIS/Windows is to use an Isapi Filter - as documented at http://neosmart.net/blog/archives/291 . The various steps mentioned below *completely* fail when a rewrite engine is employed, since IIS will *never* return a non-existent path (i.e. the actual pretty-URI used) via its server variables.
This also applies to accessing index.php via a folder.
For instance, calls made to /folder/ will appear as /folder/index.php and not /folder/.
The fix is to use the ISAPI filter provided at http://neosmart.net/blog/archives/291
You don't have to modify any of the actual scripts once this filter is in place - it automatically intercepts calls to REQUEST_URI and replaces them with the actual user-entered path.
09-Nov-2006 06:59
I'm sure this is elsewhere, but since 'chris dot chaudruc at gmail dot com' posted his example, I thought I would share a quick function I use to force HTTPS protocol on a page, without having to know the scripts name...
<?php
function ForceHTTPS()
{
if( $_SERVER['HTTPS'] != "on" )
{
$new_url = "https://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
header("Location: $new_url");
exit;
}
}
?>
Correct me if part of this doesn't work right. I've always used *nix based servers for PHP, so I might not be aware of certain windows limitations. Thanks.
19-Sep-2006 12:16
If you want to use a form with multiple checkboxes (e.g. one per row) and assign the same name to each checkbox then the name needs to end with []. This tells PHP to put all checked values into an array variable.
For example:
<input type="checkbox" name="id[]" value="value_1">
<input type="checkbox" name="id[]" value="value_2">
..
<input type="checkbox" name="id[]" value="value_x">
You can now retrieve all values by using:
$values = $_POST['id'];
If the name does not end with [], then only a single value will be available via the $_POST variable even if the user checks several checkboxes.
05-May-2006 10:19
Refer to CanonicalName if you are not getting the ServerName in the $_SERVER[SERVER_NAME] variable....This was a pain to figure out for me...now it works as expected by turning canonical naming on.
http://www.apacheref.com/ref/http_core/UseCanonicalName.html
26-Apr-2006 05:24
Be careful with HTTP_HOST behind a proxy server. Use these instead.
[HTTP_X_FORWARDED_FOR]
[HTTP_X_FORWARDED_HOST]
[HTTP_X_FORWARDED_SERVER]
In my situation, I used [HTTP_X_FORWARDED_SERVER] in place of [HTTP_HOST] in order get the machine and hostname (www.myurl.com)
14-Apr-2006 04:18
So you have an application in your web space, with a URL such as this:
http://<host>/<installation_path>/
and pages such as
http://<host>/<installation_path>/subfolder1/subfolder2/page.php
You have a file called config.php in <installation_path> which is include()d by all pages (in subfolders or not).
How to work out <installation_path> without hard-coding it into a config file?
<?php
// this is config.php, and it is in <installation_path>
// it is included by <installation_path>/page.php
// it is included by <installation_path>/subfolder/page2.php
// etc
$_REAL_SCRIPT_DIR = realpath(dirname($_SERVER['SCRIPT_FILENAME'])); // filesystem path of this page's directory (page.php)
$_REAL_BASE_DIR = realpath(dirname(__FILE__)); // filesystem path of this file's directory (config.php)
$_MY_PATH_PART = substr( $_REAL_SCRIPT_DIR, strlen($_REAL_BASE_DIR)); // just the subfolder part between <installation_path> and the page
$INSTALLATION_PATH = $_MY_PATH_PART
? substr( dirname($_SERVER['SCRIPT_NAME']), 0, -strlen($_MY_PATH_PART) )
: dirname($_SERVER['SCRIPT_NAME'])
; // we subtract the subfolder part from the end of <installation_path>, leaving us with just <installation_path> :)
?>
03-Apr-2006 12:11
To convert query string parameter values ($_GET, $_REQUEST), which include escaped Unicode values resulting from applying the JavaScript "escape" function to a Unicode string (%uNNNN%uNNNN%uNNNN) fast and simple is to use PECL JSON extension:
function JavaScript_Unicode_URL_2_Str($js_uni_str) {
$res = preg_replace('/%u([[:alnum:]]{4})/', '\\u\1', $js_uni_str);
$res = str_replace('"', '\"', $res); // if in str "
$res = json_decode('["'.$res.'"]'); // JavaScrip array with string element
$res = $res[0];
$res = iconv('UTF-8', ini_get('default_charset'), $res);
return $res;
}
I was unable to convince my hosting company to change their installation of PHP and therefore had to find my own way to computer $_SERVER["DOCUMENT_ROOT"]. I eventually settled on the following, which is a combination of earlier notes (with some typos corrected):
<?php
if ( ! isset($_SERVER['DOCUMENT_ROOT'] ) )
$_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/', substr(
$_SERVER['SCRIPT_FILENAME'], 0, 0-strlen($_SERVER['PHP_SELF']) ) );
?>
30-Mar-2006 12:24
Note that PHP_SELF will not be equal to REQUEST_URI under Apache if mod_rewrite has been used to move one URL to another--PHP_SELF will contain the rewritten address, and REQUEST_URI will contain the URL the user sees in their browser.
07-Mar-2006 11:35
$_GET may not handle query string parameter values which include escaped Unicode values resulting from applying the JavaScript "escape" function to a Unicode string.
To handle this the query parameter value can be obtained using a function such as:
function getQueryParameter ($strParam) {
$aParamList = explode('&', $_SERVER['QUERY_STRING']);
$i = 0;
while ($i < count($aParamList)) {
$aParam = split('=', $aParamList[$i]);
if ($strParam == $aParam[0]) {
return $aParam[1];
}
}
return "";
}
or by directly building an array or query string values and then processing the parameter string using a function such as the "unescape" function which can be found at http://www.kanolife.com/escape/2006/03/unicode-url-escapes-in-php.html (or http://www.kanolife.com/escape/ for related info).
28-Feb-2006 10:00
Note that it's a very, very bad idea to append to global variables in a loop, unless you really, really mean to do so in a global context. I just a while ago hung my server with a snippet of code like this:
<?php
$host = $_SERVER['HTTP_HOST'];
$uri = rtrim($_SERVER['PHP_SELF'], "/\\");
$GLOBALS['SITE_ROOT'] = "http://$host$uri";
while ($i < somenumber)
readfile($GLOBALS['SITE_ROOT'] = $GLOBALS['SITE_ROOT'] . '/this/file.php');
$i++
}
?>
While it is an entertaining and unusual method of creating very long URLs and breaking servers, it's a pretty awesomely bad idea
(Especially considering that the script in question ran concurrently with others of it's type, so the value in $GLOBALS['SITE_ROOT'] was unknown.)
22-Feb-2006 06:05
Also on using IPs to look up country & city, note that what you get might not be entirely accurate. If their ISP is based in a different city or province/state, the IPs may be owned by the head office, and used across several areas.
You also have rarer situations where they might be SSHed into another server, on the road, at work, at a friend's... It's a nice idea, but as the example code shows, it should only be used to set defaults.
20-Jan-2006 06:05
The solution advanced by info at meshkaat dot com does not work correctly on machines with IIS configured to use
a virtual directory as the launch point. The address strings for $_SERVER['SCRIPT_FILENAME'] and $_SERVER['PHP_SELF'] will not necessarily have the same name for the highest level directory in $_SERVER['PHP_SELF'], and therefore this solution will not return the proper value.
12-Jan-2006 05:57
Under Windows XP SP2 and IIS, $_SERVER('x') returns a path using forward slash '/' as the separator, where x is:
PHP_SELF, SCRIPT_NAME
These arguments, however, all return a path using backward slash, '\' as the separator:
__FILE__, SCRIPT_FILENAME, and DOCUMENT_ROOT (if you use one of the methods mentioned previously).
Also note that if the name of the last directory in the document root includes a space, the methods described above for setting DOCUMENT_ROOT will return a value that drops the everything past the space.
30-Nov-2005 05:17
Since $_SERVER['DOCUMENT_ROOT'] is not always present, the following will provide it where $_SERVER dosen't.
<?php
function resolveDocumentRoot() {
$current_script = dirname($_SERVER['SCRIPT_NAME']);
$current_path = dirname($_