extract
(PHP 4, PHP 5)
extract — 配列からシンボルテーブルに変数をインポートする
説明
&$var_array
[, int $extract_type = EXTR_OVERWRITE
[, string $prefix = NULL
]] )配列からシンボルテーブルに変数をインポートします。
各キーについて変数名として有効であるかどうか、 そして、シンボルテーブルの既存の変数と衝突しないかどうかを確認します。
パラメータ
-
var_array -
この関数は連想配列
var_arrayを引数とし、そのキーを変数名、値を変数の値として処理します。 各キー/値の組に関して、extract_typeおよびprefixパラメータに基づき、 現在のシンボルテーブルに変数を一つ作成します。連想配列を使用する必要があります。
EXTR_PREFIX_ALLまたはEXTR_PREFIX_INVALIDを使用しない限り、 数値添字の配列には結果は出力されません。 -
extract_type -
無効または数値キーおよび衝突に関する対処法は、
extract_typeで定義されます。 これは以下の値のどれかとなります。-
EXTR_OVERWRITE - 衝突があった場合、存在する変数が上書きされます。
-
EXTR_SKIP - 衝突があった場合、存在する変数は上書きされません。
-
EXTR_PREFIX_SAME -
衝突があった場合、
prefixを前につけた新しい変数となります。 -
EXTR_PREFIX_ALL -
全ての変数の前に
prefixを付けます。 -
EXTR_PREFIX_INVALID -
無効または数値の変数名のみに接頭辞
prefixを付けます。 -
EXTR_IF_EXISTS - 現在のシンボルテーブルに既に存在する場合にのみ上書きします。 例えば $_REQUEST 以外にあなたが定義した変数のみを展開し 有効な変数としたいような場合に有用です。
-
EXTR_PREFIX_IF_EXISTS - 同じ変数だが接頭辞をつけていないバージョンの変数が 現在のシンボルテーブルに存在する場合にのみ 変数を生成します。
-
EXTR_REFS -
変数を参照として展開します。
これはインポート済みの変数が、
var_arrayパラメータの値に常に参照付けられることを意味します。 このフラグを単独で使用するか、 あるいはextract_typeと和算することにより、 他のフラグとそれを組み合わせることができます。
extract_typeが指定されない場合、EXTR_OVERWRITEとみなされます。 -
-
prefix -
prefixは、extract_typeがEXTR_PREFIX_SAME、EXTR_PREFIX_ALL、EXTR_PREFIX_INVALIDあるいはEXTR_PREFIX_IF_EXISTSの場合にのみ必要であることに注意してください。 接頭辞を付けた変数名が有効な変数名でない場合、 この変数はシンボルテーブルにインポートされません。接頭辞は、 アンダースコア文字で配列のキーから自動的に分割されます。
返り値
シンボルテーブルにインポートした変数の数を返します。
変更履歴
| バージョン | 説明 |
|---|---|
| 4.3.0 |
EXTR_REFS が追加されました。
|
| 4.2.0 |
EXTR_IF_EXISTS と EXTR_PREFIX_IF_EXISTS
が追加されました。
|
| 4.0.5 |
この関数は、取り込んだ変数の数を返すようになりました。
EXTR_PREFIX_INVALID が追加されました。
EXTR_PREFIX_ALL が数値変数も扱ううようになりました。
|
例
例1 extract() の例
extract の使用例としては、シンボルテーブルに wddx_deserialize() から返された連想配列を インポートすることが考えられます。
<?php
/* $var_array はwddx_deserializeから返された配列と仮定します */
$size = "large";
$var_array = array("color" => "blue",
"size" => "medium",
"shape" => "sphere");
extract($var_array, EXTR_PREFIX_SAME, "wddx");
echo "$color, $size, $shape, $wddx_size\n";
?>
上の例の出力は以下となります。
blue, large, sphere, medium
EXTR_PREFIX_SAME を指定したため、$size
は上書きされず、$wddx_size が作成されます。
EXTR_SKIP が指定された場合、$wddx_size は作成されません。
EXTR_OVERWRITE
の場合は、$size の値は "medium" となります。
EXTR_PREFIX_ALL の場合は新規の変数
$wddx_color,
$wddx_size, $wddx_shape
が作成されます。
注意
extract() をユーザー入力
($_GET や $_FILES など)
のような信頼できないデータについて使用しないでください。
もし行う場合、例えば
register_globals
を信頼しているような古いコードを一時的に実行したい場合、
EXTR_SKIP のような
extract_type
の値が上書きされていないことを確認してください。そして
php.ini の
variables_order
で定義されたものと同じ順で展開すべきであることに留意してください。
注意:
register_globals が on の状態で $_FILES に対して extract() を実行して
EXTR_SKIPを指定すると、 その結果に驚くことでしょう。警告これは決しておすすめする方法ではなく、 単にドキュメントとしての完全性を求めてここに書いているだけです。 register_globals を使ったり、$_FILES のような信頼できないデータに対して extract() を使ったりすることは非推奨となっています。 先に説明したようにセキュリティ上のリスクがあるからです。 もしこの問題に遭遇したならば、 まずいコーディング作法を少なくともふたつ使っているということになります。
おそらくこんな結果になることを期待しているでしょう。<?php
/* $testfile にはアップロードされたファイルの名前が入っており、
register_globals が on であるものとします */
var_dump($testfile);
extract($_FILES, EXTR_SKIP);
var_dump($testfile);
var_dump($testfile['tmp_name']);
?>しかし、実際にはこのようになります。string(14) "/tmp/phpgCCPX8" array(5) { ["name"]=> string(10) "somefile.txt" ["type"]=> string(24) "application/octet-stream" ["tmp_name"]=> string(14) "/tmp/phpgCCPX8" ["error"]=> int(0) ["size"]=> int(4208) } string(14) "/tmp/phpgCCPX8"string(14) "/tmp/phpgCCPX8" string(14) "/tmp/phpgCCPX8" string(1) "/"これは、register_globals が on の場合は extract() がコールされた時点で既にグローバルスコープに $testfile が存在するからです。 そして
EXTR_SKIPが指定されているので、 $testfile が$_FILES配列の内容で上書きされることはありません。 $testfile はそのまま文字列として残るわけです。 文字列は配列構文を使ってもアクセスでき、 非数値の文字列 tmp_name は 0 と解釈されるので、PHP は $testfile['tmp_name'] を $testfile[0] とみなします。