配列

PHPの配列は、実際には順番付けられたマップです。マップは、 キー にマップする型で す。この型は、いくつかの手法で最適化されます。このため、実際の配列 またはリスト(ベクトル)、(あるマップの実装である)ハッシュテーブル、 ディレクトリ、コレクション、スタック、キュー等として使用することが 可能です。PHPの配列には他のPHP配列を値として保持することができるた め、非常に簡単にツリー構造を表現することが可能です。

これらの構造に関する説明は、本マニュアルの範囲外ですが、これらの構 造に各々に関する例を少なくとも一つ見付けることが可能です。これらの 構造に関するより詳細な情報については、データ構造に関する良書を購入 して下さい。

構文

array() で指定

配列 は、言語構造 array() で作成 することが可能です。この構造は、特定の数のカンマで区切られた key = value の組を引数とします。

key は、整数 または 文字列です。 あるキーが、整数の標準的な表現形式である場合、 そのように解釈されます。(つまり、 '8'8 として解釈されます。一方、 '08''08' として解釈されま す。)

値は、何でも構いません。

キーを省略した場合、整数添字の最大値が使用され、新しいキーはそ の最大値+1となります。整数値は負の数となる可能性があるため、 負の添字も有りえます。例えば、最高時の添字が -6 の場合、次のキーは -5 となります。 整数添字がまだ存在しない場合、キーは 0 (ゼロ)となります。 値が既に代入されているキーを指定した場合、元の値は上書きされます。

キーとして true を使用すると、 integer 1 がキーとして評価されます。 キーとして false を使用すると、 integer 0 がキーとして評価されます。 キーとして NULL を使用すると、空の文字列として評価 されます。キーとして空の文字列を使用すると、空の文字列のキーとその値を 作成(または上書き)します。空の括弧を用いた場合と同じではありません。

配列またはオブジェクトをキーとして使用することはできません。 これを行なうと、warning: Illegal offset type を発生します。

array( [

  key

 = ] 

  value


     , ...
     )
// 

  key

  string

 または非負の 整数のどちらか
// 

  value

 は何でも可


角括弧構文で作成/修正

明示的に値を設定することにより、既存の配列を修正することも可能で す。

これは、角括弧の中にキーを指定することにより、配列に値を代入する ことにより行うことが可能です。キーを省略することも可能です。この 場合、空の角括弧(" [] ")の変数名として追加して 下さい。

$arr[

  key

] = 

  value

;
$arr[] = 

  value

;
// 

  key

  string

 または非負の
// 整数のどちらかです。

// 

  value

 は何でもかまいません
$arr がまだ存在しない場合、作成されます。 配列を指定する別の手段でもあります。ある値を変更するには、新し い値に値を代入します。キー/値の組を削除したい場合には、 unset() を使用する必要があります。

有用な関数

配列で使用する便利な関数がたくさんあります。 配列関数 の節を参照下さい。

注意 unset() 関数は配列のキーを削除することが出来ます。 ただし、これによってインデックスの再構築が行われるわけでは ない ということに気をつけてください。

$a = array( 1 =  'one', 2 =  'two', 3 =  'three' );
unset( $a[2] );
/* これにより配列は以下の様に定義されます。
   $a = array( 1= 'one', 3= 'three');
   こうではありません:
   $a = array( 1 =  'one', 2 =  'three');
*/


制御構造 foreach が配列用に限定して存在します。この構造は、配列の要素に簡単に連続 的にアクセスする手段を提供します。

配列ですべきこととしてはならないこと

なぜ、 $foo[bar] は使用できないのか?

古いスクリプトで次のような構文を見たことがあるかもしれません。

$foo[bar] = 'enemy';
echo $foo[bar];
// 等
これは間違っていますが、動作します。では、なぜ間違っているのでしょ う? その理由は、 構文 の節に記述したように、角括弧の間 (' [ 'および' ] ')に式がなけれ ばならないためです。これは、次のように書くことが可能であることを 意味します。
echo $arr[ foo(true) ];
これは、関数の出力を配列の添字として使用する例です。PHPは定数に ついても認識します。前に E_* を見たことがあるか もしれません。
$error_descriptions[E_ERROR] = "A fatal error has occured";
$error_descriptions[E_WARNING] = "PHP issued a warning";
$error_descriptions[E_NOTICE] = "This is just an informal notice";
最初の例の bar と全く同様に E_ERROR も有効な添字であることに注意して下さ い。しかし、実際には最後の例は次のように書くことと同じです。
$error_descriptions[1] = "A fatal error has occured";
$error_descriptions[2] = "PHP issued a warning";
$error_descriptions[8] = "This is just an informal notice";
これは、 E_ERROR1 と等し いこと等によります。

では、なぜ $foo[bar] は動作することが可能なの でしょう? それは、 bar が定数式であることを 期待される構文で使用されているためです。しかし、この場合、 bar という名前の定数は存在しません。PHPは、 この場合、あなたが文字列 "bar" のようにリテラル bar を指定したが引用符を忘れたと仮定します。

では、なぜ間違っているのでしょう?

将来的に、PHPは他の定数またはキーワードを追加したいと思うかもし れず、問題となる可能性があります。例えば、現在でも、 単語 empty および default を使用することはできません。 これは、これらが、特別な 予約済みのキーワード である ためです。

注意 error_reportingE_ALL に変えた場合、PHPがこの構造が使用され ているところ見付ける度に警告が生成されます。この機能は、他の過 去の「機能」についても有効です。 (スクリプトに行 error_reporting(E_ALL); を 置いて下さい)

注意 2重引用符で括られた string の中で他の構文が有効です。 より詳細については、 文字列の中の変数 を参照下さい。

PHPの配列型は非常に解りにくいため、ここで、配列の強力な機能を示す いくつかの例を紹介します。

// this
$a = array( 'color' =  'red'
          , 'taste' =  'sweet'
          , 'shape' =  'round'
          , 'name'  =  'apple'
          ,            4        // キーは0になります
          );

// これは以下と完全に同じです。
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[]        = 4;        // キーは0になります

$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// この結果は配列 array( 0 =  'a' , 1 =  'b' , 2 =  'c' )
// または単に array('a', 'b', 'c') となります


例 7-4array()の使用例

// マップを行う配列
$map = array( 'version'    =  4
            , 'OS'         =  'Linux'
            , 'lang'       =  'english'
            , 'short_tags' =  true
            );
            
// 数値キーのみを有する
$array = array( 7
              , 8
              , 0
              , 156
              , -10
              );
// これは、array( 0 =  7, 1 =  8, ...) と同じです

$switching = array(         10 // key = 0
                  , 5    =   6
                  , 3    =   7 
                  , 'a'  =   4
                  ,         11 // key = 6 (最大の添字は5です)
                  , '8'  =   2 // key = 8 (整数!)
                  , '02' =  77 // key = '02'
                  , 0    =  12 // 値10は12で上書きされます
                  );
                  
// empty array
$empty = array();

例 7-5コレクション

$colors = array('red','blue','green','yellow');

foreach ( $colors as $color ) {
    echo "Do you like $color?\n";
}

/* 出力:
Do you like red?
Do you like blue?
Do you like green?
Do you like yellow?
*/

配列の値をこのようなループで直接変更することはできないことに注意 して下さい。 これを解決するには、次のようにします。

例 7-6コレクション

foreach ( $colors as $key =  $color ) {
    // 動作しない:
    //$color = strtoupper($color);
    
    // 動作する:
    $colors[$key] = strtoupper($color);
}
print_r($colors);

/* 出力:
Array
(
    [0] =  RED
    [1] =  BLUE
    [2] =  GREEN
    [3] =  YELLOW
)
*/


この例は、1から始まる配列を作成します。

例 7-71から始まる添字

$firstquarter  = array(1 =  'January', 'February', 'March');
print_r($firstquarter);

/* 出力:
Array 
(
    [1] =  'January'
    [2] =  'February'
    [3] =  'March'
)
*/


例 7-8配列に代入する

// ディレクトリから全てのアイテムを配列に代入する
$handle = opendir('.');
while ($file = readdir($handle)) 
{
    $files[] = $file;
}
closedir($handle);

配列には順番が付けられます。異なったソート関数を用いて順番を変更 することも可能です。より詳細な情報については、 配列関数 を参照下さい。

例 7-9配列のソート

sort($files);
print_r($files);

配列の値は何でも良いため、その値を他の配列とすることも可能です。 これにより、再帰的な配列や多次元の配列を作成することが可能です。

例 7-10再帰および多次元配列

$fruits = array ( "fruits"  =  array ( "a" =  "orange"
                                     , "b" =  "banana"
                                     , "c" =  "apple"
                                     )
                , "numbers" =  array ( 1
                                     , 2
                                     , 3
                                     , 4
                                     , 5
                                     , 6
                                     )
                , "holes"   =  array (      "first"
                                     , 5 =  "second"
                                     ,      "third"
                                     )
                );