## 配列

全ての配列関数の一覧は、配列関数 を参照ください。

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

これらのデータ構造に関する説明は本マニュアルの範囲を超えるので省略しますが、 各々について、少なくとも一つは例を示します。 この分野は広範囲にまたがり、さまざまな文献が存在します。 より詳細な情報については、それらの文献を参照ください。

### 構文

#### array() で指定

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

    array(
        key  => value,
        key2 => value2,
        key3 => value3,
        ...
    )

最後の要素のあとのカンマは、書いても書かなくてもかまいません。 配列を一行で定義する場合は、ふつうは最後のカンマを省略します。つまり、 `array(1, 2)` のほうが `array(1, 2, )` よりおすすめだということです。 しかし複数行で定義する場合は、最後のカンマをつけることが一般的です。 そうしておけば、配列の最後に要素を追加するのが容易になるからです。

> 注意:

> `array()` を `[]` で置き換えることが出来る、配列の短縮構文も使えます。

例1 シンプルな配列定義

    <?php
    $array1 = array(
        "foo" => "bar",
        "bar" => "foo",
    );

    // 配列の短縮構文
    $array2 = [
        "foo" => "bar",
        "bar" => "foo",
    ];

    var_dump($array1, $array2);
    ?>

key は、int または stringです。 value には任意の型を指定できます。

さらに、次のような key のキャストが発生します。

- 10 進数の int として妥当な形式の String は、 数値の前に `+` 記号がついていない限り、 int 型にキャストされます。 つまり、キーに `"8"` を指定すると、実際には `8` として格納されるということです。一方 `"08"` はキャストされません。これは十進数として妥当な形式ではないからです。
- floats もまた int にキャストされます。つまり、 小数部分は切り捨てられるということです。たとえばキーに `8.7` を指定すると、実際には `8` として格納されます。
- bool も int にキャストされます。つまり、 キーに `true` を指定すると実際には `1` に格納され、 同様にキーを `false` とすると実際には `0` となります。
- Null は空文字列にキャストされます。つまり、キーに `null` を指定すると、実際には `""` として格納されます。
- array や object は、キーとして使えません。 キーとして使おうとすると `Illegal offset type` という警告が発生します。

配列の宣言時に同じキーで複数の要素を指定すると、 最後に指定したものがそれまでの値を上書きします。

例2 型のキャストと値の上書きの例

    <?php
    $array = array(
        1    => "a",
        "1"  => "b",
        1.5  => "c",
        true => "d",
    );
    var_dump($array);
    ?>

上の例の出力は以下となります。

    array(1) {
      [1]=>
      string(1) "d"
    }

上の例では、すべてのキーが `1` にキャストされます。 そして後から指定した値がどんどん前の値を上書きしていき、最終的には最後に代入された `"d"` だけが残ります。

PHP においては添字配列と連想配列の間に違いはなく、配列型は 1 つだけで、 同じ配列で整数のインデックスと文字列のインデックスを同時に使えます。

例3 整数と文字列のキーの混在例

    <?php
    $array = array(
        "foo" => "bar",
        "bar" => "foo",
        100   => -100,
        -100  => 100,
    );
    var_dump($array);
    ?>

上の例の出力は以下となります。

    array(4) {
      ["foo"]=>
      string(3) "bar"
      ["bar"]=>
      string(3) "foo"
      [100]=>
      int(-100)
      [-100]=>
      int(100)
    }

key はオプションです。省略した場合、PHP はこれまでに使われた整数のキーの中で最大のものに 1 を加えた値を使います。

例4 数値添字配列でキーを省略する例

    <?php
    $array = array("foo", "bar", "hello", "world");
    var_dump($array);
    ?>

上の例の出力は以下となります。

    array(4) {
      [0]=>
      string(3) "foo"
      [1]=>
      string(3) "bar"
      [2]=>
      string(5) "hello"
      [3]=>
      string(5) "world"
    }

一部の要素にだけキーを指定することもできます。

例5 一部の要素にだけキーを指定する例

    <?php
    $array = array(
             "a",
             "b",
        6 => "c",
             "d",
    );
    var_dump($array);
    ?>

上の例の出力は以下となります。

    array(4) {
      [0]=>
      string(1) "a"
      [1]=>
      string(1) "b"
      [6]=>
      string(1) "c"
      [7]=>
      string(1) "d"
    }

ごらんの通り、最後の値である `"d"` のキーは `7` となります。それまでにキーとして使われた最大の整数が `6` だからです。

例6 複雑な型のキャストと上書きの例

以下の例は、型のキャストされた時と、要素が上書きされる時の全ての場合を示しています。

    <?php
    $array = array(
        1    => 'a',
        '1'  => 'b', // 値 "a" は "b" で上書きされます。
        1.5  => 'c', // 値 "b" は "c" で上書きされます。
        -1 => 'd',
        '01'  => 'e', // この値は数値形式の文字列ではないので、キー1を上書きしません
        '1.5' => 'f', // この値は数値形式の文字列ではないので、キー1を上書きしません
        true => 'g', // 値 "c" は "g" で上書きされます。
        false => 'h',
        '' => 'i',
        null => 'j', // 値 "i" は "j" で上書きされます。
        'k', // 値 "k" にはキー2が割り当てられます。なぜなら、これより前のキーの最大値は1だからです。
        2 => 'l', // 値 "k" は "l" で上書きされます。
    );

    var_dump($array);
    ?>

上の例の出力は以下となります。

    array(7) {
      [1]=>
      string(1) "g"
      [-1]=>
      string(1) "d"
      ["01"]=>
      string(1) "e"
      ["1.5"]=>
      string(1) "f"
      [0]=>
      string(1) "h"
      [""]=>
      string(1) "j"
      [2]=>
      string(1) "l"
    }

例7 負のインデックスの例

負の整数キー `n` を代入すると、PHP は次のキーを `n+1` に代入します。

    <?php
    $array = [];

    $array[-5] = 1;
    $array[] = 2;

    var_dump($array);
    ?>

上の例の出力は以下となります。

    array(2) {
      [-5]=>
      int(1)
      [-4]=>
      int(2)
    }

警告

PHP 8.3.0 より前のバージョンでは、負の整数キー `n` を代入すると、 次のキーは `0` に代入されていました。 そのため、前の例は次のように出力されていました:

    array(2) {
      [-5]=>
      int(1)
      [0]=>
      int(2)
    }

#### 角括弧構文による配列要素へのアクセス

配列の要素へのアクセスには `array[key]` 構文を使います。

例8 配列の要素へのアクセス

    <?php
    $array = array(
        "foo" => "bar",
        42    => 24,
        "multi" => array(
             "dimensional" => array(
                 "array" => "foo"
             )
        )
    );

    var_dump($array["foo"]);
    var_dump($array[42]);
    var_dump($array["multi"]["dimensional"]["array"]);
    ?>

上の例の出力は以下となります。

    string(3) "bar"
    int(24)
    string(3) "foo"

> 注意:

> PHP 8.0.0 より前のバージョンでは、 配列の要素にアクセスするときに、 角括弧と波括弧がどちらも同じ意味で使えていました。 (つまり、この例で `$array[42]` と `$array{42}` は同じものを表しているということです)。 波括弧で配列にアクセスする文法は、 PHP 7.4.0 以降は非推奨になり、 PHP 8.0.0 以降はサポートされなくなっています。

例9 配列のデリファレンス

    <?php
    function getArray() {
        return array(1, 2, 3);
    }

    $secondElement = getArray()[1];

    var_dump($secondElement);
    ?>

> 注意:

> 配列に定義されていないキーへアクセスしたときの挙動は、 未定義の変数にアクセスしたときと同じです。 つまり、`E_WARNING` レベルの警告 (PHP 8.0.0 より前のバージョンでは `E_NOTICE`) が発生し、結果が `null` になります。

> 注意:

> 配列で文字列以外のスカラー値をデリファレンスした場合は、 返される結果は `null` となります。 PHP 7.4.0 より前のバージョンでは、何もエラーは発生しませんでした。 PHP 7.4.0 以降では、`E_NOTICE` が発生します。 PHP 8.0.0 以降では、`E_WARNING` が発生します。

#### 角括弧構文で作成/修正

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

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

    $arr[key] = value;
    $arr[] = value;
    // key は string または
    // intのどちらかです。
    // value の型は、何でもかまいません。

$arr がまだ存在しない場合、 あるいは `null` や `false` に設定されている場合は、 新しく配列を作成します。 つまり、これは配列を作成する方法のひとつでもあります。 とはいえ、この方法を使うことはおすすめしません。なぜなら、既に $arr に何らかの値 (リクエスト変数からの文字列など) が入っている場合にはその値がそのまま残り、 `[]` が実際には 文字列アクセス演算子 を表してしまうからです。 変数を初期化するときには、直接代入するほうがよいでしょう。

> 注意: PHP 7.1.0 以降では、文字列に空のインデックス演算子を適用すると 致命的なエラーが発生するようになりました。 これまでのバージョンではエラーにならず、文字列が配列に変換されていました。

> 注意: PHP 8.1.0 以降では、 `false` に設定している値から新しく配列を作成することは推奨されません。 `null` や未定義の値から配列を新しく作成することはまだ許可されています。

ある値を変更するには、 新しい値に値を代入します。特定のキー/値の組を削除したい場合には、 unset() を使用する必要があります。

例10 角括弧と配列の使用

    <?php
    $arr = array(5 => 1, 12 => 2);

    $arr[] = 56;    // このスクリプトのこの位置に記述した場合、
                    // $arr[13] = 56; と同じです

    $arr["x"] = 42; // キー"x"の新しい要素を配列に追加します

    unset($arr[5]); // 配列から要素を削除します

    var_dump($arr);

    unset($arr);    // 配列全体を削除します

    var_dump($arr);
    ?>

> 注意: キーを省略した場合、キーは使用されている整数添字の最大値 + `1` になります。配列に正の整数添字が存在しない場合は、 キーは `0` となります。 PHP 8.3.0 以降では、負の整数になることもあります。

> 次のキー生成において、オフセットとして使われる整数値 (添字の最大値) に対応するエントリーが、 必ずしも配列内に存在するわけではないことに注意してください。 しかし、その値は、多くの場合、 配列にある整数のキー値の最大値と等しいはずです。以下に例を示します。

>     <?php
>     // 簡単な配列を生成します。
>     $array = array(1, 2, 3, 4, 5);
>     print_r($array);

>     // 全てのアイテムを削除しますが、配列自体は削除しないでおきます。
>     foreach ($array as $i => $value) {
>         unset($array[$i]);
>     }
>     print_r($array);

>     // アイテムを追加します(新しい添え字は0ではなく
>     // 5となることに注意)
>     $array[] = 6;
>     print_r($array);

>     // 添え字を振りなおします。
>     $array = array_values($array);
>     $array[] = 7;
>     print_r($array);
>     ?>

> 上の例の出力は以下となります。

>     Array
>     (
>         [0] => 1
>         [1] => 2
>         [2] => 3
>         [3] => 4
>         [4] => 5
>     )
>     Array
>     (
>     )
>     Array
>     (
>         [5] => 6
>     )
>     Array
>     (
>         [0] => 6
>         [1] => 7
>     )

#### 配列の分解

配列は、言語構造 `[]` (PHP 7.1.0 以降) または、list() を使って分解することができます。 これらの言語構造は、 配列を個別の値に分解する用途に使えます。

例11 配列の分解

    <?php
    $source_array = ['foo', 'bar', 'baz'];

    [$foo, $bar, $baz] = $source_array;

    echo $foo, PHP_EOL;    // "foo" を出力します。
    echo $bar, PHP_EOL;    // "bar" を出力します。
    echo $baz, PHP_EOL;    // "baz" を出力します。
    ?>

これは、多次元配列を `foreach` で反復処理しながら分解する用途に使えます。

例12 foreach での配列の分解

    <?php
    $source_array = [
        [1, 'John'],
        [2, 'Jane'],
    ];

    foreach ($source_array as [$id, $name]) {
        echo "{$id}: '{$name}'\n";
    }
    ?>

変数が与えられない配列の要素は無視されます。 配列の分解は、常にインデックス `0` から始まります。

例13 要素を無視する

    <?php
    $source_array = ['foo', 'bar', 'baz'];

    // インデックス2の要素を、変数 $baz に代入します
    [, , $baz] = $source_array;

    echo $baz;    // "baz" を出力します。
    ?>

PHP 7.1.0 以降では、 連想配列も分解できるようになりました。 数値をキーとした配列の右側の要素を、 インデックスを明示的に指定することで簡単に選択できるようになっています。

例14 連想配列の分解

    <?php
    $source_array = ['foo' => 1, 'bar' => 2, 'baz' => 3];

    // インデックス 'baz' の要素を、変数 $three に代入します。
    ['baz' => $three] = $source_array;

    echo $three, PHP_EOL;  // 3 を出力します。

    $source_array = ['foo', 'bar', 'baz'];

    // インデックス 2 の要素を、変数 $baz に代入します。
    [2 => $baz] = $source_array;

    echo $baz, PHP_EOL;    // "baz" を出力します。
    ?>

配列の分解を使うと、2つの変数を簡単に入れ替えることができます。

例15 2つの変数の入れ替え

    <?php
    $a = 1;
    $b = 2;

    [$b, $a] = [$a, $b];

    echo $a, PHP_EOL;    // 2 を出力します。
    echo $b, PHP_EOL;    // 1 を出力します。
    ?>

> 注意:

> 分解時に値を代入する際には、`...` 演算子はサポートされていません。

> 注意:

> 定義されていない配列のキーにアクセスしようとすると、 未定義の変数にアクセスする場合と同じ扱いになります。 つまり、`E_WARNING` レベルの警告 (PHP 8.0.0 より前のバージョンでは `E_NOTICE`) が発生し、結果が `null` になります。

> 注意:

> スカラー値を分解すると、全ての変数に `null` が代入されます。

### 有用な関数

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

> 注意:

> unset()関数は配列のキーを削除することが出来ます。 ただし、これによってインデックスの再構築が行われるわけではないことに 注意してください。 "通常の整数添字" (0 から始まり、1 つずつ増加) のみを使用している場合、 array_values() を用いてインデックスを再構築することができます。

> 例16 中間にある要素を unset する

>     <?php
>     $a = array(1 => 'one', 2 => 'two', 3 => 'three');

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

>     $b = array_values($a);
>     // $b は、array(0 => 'one', 1 =>'three')となります
>     var_dump($b);
>     ?>

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

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

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

連想配列の添字の前後は常に引用符で括る必要があります。 例えば、$foo[bar] ではなく $foo['bar'] を使用してください。 しかし、$foo[bar] はなぜ誤りなのでしょうか? 古いスクリプトで次のような構文を見たことがあるかもしれません。

    <?php
    $foo[bar] = 'enemy';
    echo $foo[bar];
    // etc
    ?>

これは間違っていますが、動作します。では、なぜ間違っているのでしょう? それは、このコードには文字列 (`'bar'` - 引用符で括られている) ではなく未定義の定数 (`bar`) が使用されているためです。 下位互換性の維持のため、未定義の定数は同じ名前の文字列に自動的に変換されます。 そのため、このコードは動作します。 例えば、`bar` という名前の定義されていない定数があるとすると、 PHP は `'bar'` という文字列でそれを置換して使用します。

警告

生の文字列を未定義の定数として扱う振る舞いは、 `E_NOTICE` レベルの警告が発生します。 この振る舞いは PHP 7.2.0 以降は推奨されなくなり、 `E_WARNING` レベルの警告が発生します。 PHP 8.0.0 以降は、この振る舞いは削除され、 Error 例外がスローされるようになっています。

これは、キーを 常に クォートするという意味ではありません。 定数や 変数 をキーとして使う際には、クォートしてしまうと PHP はそれを解釈できなくなってしまいます。

例17 キーのクォート

    <?php
    error_reporting(E_ALL);
    ini_set('display_errors', true);
    ini_set('html_errors', false);

    // 単純な配列
    $array = array(1, 2);
    $count = count($array);

    for ($i = 0; $i < $count; $i++) {
        echo "\nChecking $i: \n";
        echo "Bad: " . $array['$i'] . "\n";
        echo "Good: " . $array[$i] . "\n";
        echo "Bad: {$array['$i']}\n";
        echo "Good: {$array[$i]}\n";
    }
    ?>

上の例の出力は以下となります。

    Checking 0:
    Notice: Undefined index:  $i in /path/to/script.html on line 9
    Bad:
    Good: 1
    Notice: Undefined index:  $i in /path/to/script.html on line 11
    Bad:
    Good: 1

    Checking 1:
    Notice: Undefined index:  $i in /path/to/script.html on line 9
    Bad:
    Good: 2
    Notice: Undefined index:  $i in /path/to/script.html on line 11
    Bad:
    Good: 2

この具体例を以下に示します。

例18 その他の例

    <?php
    // エラーを全て表示するよう設定
    error_reporting(E_ALL);

    $arr = array('fruit' => 'apple', 'veggie' => 'carrot');

    // 正しい
    echo $arr['fruit'], PHP_EOL;  // apple
    echo $arr['veggie'], PHP_EOL; // carrot

    // 間違い。未定義の定数fruitを使用しているため動作せず、
    // PHP がエラーを発生させます。
    //
    // Error: Undefined constant "fruit"
    try {
        echo $arr[fruit];
    } catch (Error $e) {
        echo get_class($e), ': ', $e->getMessage(), PHP_EOL;
    }

    // 検証のため、定数を定義してみましょう。
    // fruitという名前の定数に値'veggie'を代入します。
    define('fruit', 'veggie');

    // ここでは、出力が異なることに注意してください。
    echo $arr['fruit'], PHP_EOL;  // apple
    echo $arr[fruit], PHP_EOL;    // carrot

    // 以下は文字列の中であるためOKです。定数は、文字列の中では解釈されな
    // いため、エラーはここでは発生しません。
    echo "Hello $arr[fruit]", PHP_EOL;      // Hello apple

    // 例外が１つあり、文字列の中で波括弧で配列を括った場合には、
    // 定数が解釈されます
    echo "Hello {$arr[fruit]}", PHP_EOL;    // Hello carrot
    echo "Hello {$arr['fruit']}", PHP_EOL;  // Hello apple

    // 文字列結合で同じことをすることもできます
    echo "Hello " . $arr['fruit'], PHP_EOL; // Hello apple
    ?>

    <?php
    // これは動作せず、以下のようなパースエラーを発生します:
    // Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
    // 文字列の中でスーパーグローバルを使用した場合も無論同様です。
    print "Hello $arr['fruit']";
    print "Hello $_GET['foo']";
    ?>

構文 で説明した通り、角括弧 ('`[`' および '`]`') の間には、式がなければなりません。つまり、 次のように書けるということです。

    <?php
    echo $arr[somefunc($bar)];
    ?>

これは、関数の戻り値を配列の添字として使用する例です。PHP は定数についても認識します。以下のような `E_*` の使用例を見たことがあるかもしれません。

    <?php
    $error_descriptions[E_ERROR]   = "A fatal error has occurred";
    $error_descriptions[E_WARNING] = "PHP issued a warning";
    $error_descriptions[E_NOTICE]  = "This is just an informal notice";
    ?>

最初の例の `bar` と全く同様に `E_ERROR` も有効な添字であることに注意してください。 しかし、実際には最後の例は次のように書くことと同じです。

    <?php
    $error_descriptions[1] = "A fatal error has occurred";
    $error_descriptions[2] = "PHP issued a warning";
    $error_descriptions[8] = "This is just an informal notice";
    ?>

これは、`E_ERROR` が `1` と等しいこと等によります。

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

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

> 注意: 二重引用符で括られた string の中では 引用符で配列の添字を括らないことができ、このため、 `"$foo[bar]"` は有効です。 この理由の詳細については、上記の例や 文字列中での変数のパースを参照ください。

### 配列への変換

int, float, string, bool, resourceのいずれの型においても、 array に変換する場合、 最初のスカラー値が割り当てられている一つの要素 (添字は 0) を持つ配列を得ることになります。 言い換えると、`(array) $scalarValue` は、`array($scalarValue)` と全く同じです。

objectを配列にする場合には、配列の要素として オブジェクトの属性 (メンバ変数) を持つ配列を得ることになります。 添字はメンバ変数名となりますが、いくつか注意すべき例外があります。 整数のプロパティはアクセス不能になります。 private 変数の場合、変数名の頭にクラス名がつきます。また、 protected 変数の場合は、変数名の頭に '*' がつきます。 このとき、頭に追加される値の前後に `NUL` バイトがついてきます。 未初期化の 型付きプロパティ は黙って捨てられます。

例19 配列への変換

    <?php

    class A {
        private $B;
        protected $C;
        public $D;
        function __construct()
        {
            $this->{1} = null;
        }
    }
    var_export((array) new A());
    ?>

上の例の出力は以下となります。

    array (
      '' . "\0" . 'A' . "\0" . 'B' => NULL,
      '' . "\0" . '*' . "\0" . 'C' => NULL,
      'D' => NULL,
      1 => NULL,
    )

これらの `NUL` バイトは、以下のような予期せぬ振る舞いをすることがあります:

例20 オブジェクトを配列にキャストする

    <?php

    class A {
        private $A; // これは '\0A\0A' となります
    }

    class B extends A {
        private $A; // これは '\0B\0A' となります
        public $AA; // これは 'AA' となります
    }

    var_dump((array) new B());
    ?>

上の例の出力は以下となります。

    array(3) {
      ["BA"]=>
      NULL
      ["AA"]=>
      NULL
      ["AA"]=>
      NULL
    }

上の例では 'AA' というキーがふたつあるように見えますが、 そのうちひとつは、実際は '\0A\0A' ということになります。

`null` を配列に変換すると、空の配列を得ます。

### 比較

array_diff() と 配列演算子 を用いると、配列を比較することができます。

### 配列のアンパック

配列の前に `...` を付けると、 配列を定義する際に、その配列の値を展開(アンパック)させることができます。 配列と、Traversable を実装したオブジェクトを展開させることができます。 `...` を使った配列のアンパックは、 PHP 7.4.0 以降で利用可能です。これは、スプレッド演算子とも呼ばれます。

配列のアンパックは、配列中で何度でも行うことができます。 `...` の前後に通常の要素を置くこともできます:

例21 簡単な配列のアンパック

    <?php
    // 配列の短縮構文を使っています。
    // array() 記法も使えます。
    $arr1 = [1, 2, 3];
    $arr2 = [...$arr1]; // [1, 2, 3]
    $arr3 = [0, ...$arr1]; // [0, 1, 2, 3]
    $arr4 = [...$arr1, ...$arr2, 111]; // [1, 2, 3, 1, 2, 3, 111]
    $arr5 = [...$arr1, ...$arr1]; // [1, 2, 3, 1, 2, 3]

    function getArr() {
      return ['a', 'b'];
    }
    $arr6 = [...getArr(), 'c' => 'd']; // ['a', 'b', 'c' => 'd']

    var_dump($arr1, $arr2, $arr3, $arr4, $arr5, $arr6);
    ?>

`...` を使ったアンパックの動作は、 array_merge() 関数の仕様に従います。 つまり、キーが文字列の場合は後に指定された値が前の値を上書きしますし、 キーが整数の場合は、ゼロから値が振り直されます:

例22 キーが重複した場合の配列のアンパック

    <?php
    // キーが文字列の場合
    $arr1 = ["a" => 1];
    $arr2 = ["a" => 2];
    $arr3 = ["a" => 0, ...$arr1, ...$arr2];
    var_dump($arr3); // ["a" => 2]

    // キーが整数の場合
    $arr4 = [1, 2, 3];
    $arr5 = [4, 5, 6];
    $arr6 = [...$arr4, ...$arr5];
    var_dump($arr6); // [1, 2, 3, 4, 5, 6]
    // $arr6 は、 [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6] と同義です。
    // ここでは、キーの値は保存されません。
    ?>

> 注意:

> キーが整数でも文字列でもない場合は、 TypeError がスローされます。 そのようなキーを持つ値は、 Traversable オブジェクト経由でしか生成できません。

> 注意:

> PHP 8.1 より前のバージョンでは、 キーが文字列の場合に、アンパックをサポートしていませんでした:

>     <?php

>     $arr1 = [1, 2, 3];
>     $arr2 = ['a' => 4];
>     $arr3 = [...$arr1, ...$arr2];
>     // Fatal error: Uncaught Error: Cannot unpack array with string keys in example.php:5

>     $arr4 = [1, 2, 3];
>     $arr5 = [4, 5];
>     $arr6 = [...$arr4, ...$arr5]; // 動作します。 [1, 2, 3, 4, 5]
>     ?>

### 例

PHP の配列型は、いろいろな使い方ができます。配列の強力な機能を示すため、 ここでいくつかの例を紹介します。

例23 多様な配列

    <?php
    // これは、
    $a = array( 'color' => 'red',
                'taste' => 'sweet',
                'shape' => 'round',
                'name'  => 'apple',
                4        // キーは0になります
              );

    $b = array('a', 'b', 'c');

    var_dump($a, $b);

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

    $b = array();
    $b[] = 'a';
    $b[] = 'b';
    $b[] = 'c';

    // 上のコードを実行すると、$a は次のような配列
    // array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
    // 'name' => 'apple', 0 => 4) となり、$b は
    // array(0 => 'a', 1 => 'b', 2 => 'c') あるいは単に array('a', 'b', 'c') となります

    var_dump($a, $b);
    ?>

例24 array() の使用例

    <?php
    // マップを行う配列
    $map = array( 'version'    => 4,
                  'OS'         => 'Linux',
                  'lang'       => 'english',
                  'short_tags' => true
                );
    var_dump($map);

    // 数値キーのみを有する
    // これは、array(0 => 7, 1 => 8, ...) と同じです
    $array = array( 7,
                    8,
                    0,
                    156,
                    -10
                  );
    var_dump($array);

    $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で上書きされます
                      );
    var_dump($switching);

    // 空の配列
    $empty = array();
    var_dump($empty);
    ?>

例25 コレクション

    <?php
    $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?

配列を参照渡しすることでその値を直接変更できます。

例26 ループ内での要素の変更

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

    foreach ($colors as &$color) {
        $color = mb_strtoupper($color);
    }
    unset($color); /* これ以降の $color への書き込みが
    配列の要素を書き換えてしまわないことを保証する */

    print_r($colors);
    ?>

上の例の出力は以下となります。

    Array
    (
        [0] => RED
        [1] => BLUE
        [2] => GREEN
        [3] => YELLOW
    )

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

例27 1 から始まる添字

    <?php
    $firstquarter = array(1 => 'January', 'February', 'March');
    print_r($firstquarter);
    ?>

上の例の出力は以下となります。

    Array
    (
        [1] => January
        [2] => February
        [3] => March
    )

例28 配列に代入する

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

    var_dump($files);
    ?>

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

例29 配列のソート

    <?php
    sort($files);
    print_r($files);
    ?>

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

例30 再帰および多次元配列

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

    // 上の配列の内容を取得するための例
    echo $fruits["holes"][5];    // "second" を表示します
    echo $fruits["fruits"]["a"]; // "orange" を表示します
    unset($fruits["holes"][0]);  // "first"  を削除します

    // 新しい多次元配列を作成します
    $juices["apple"]["green"] = "good";
    var_dump($juices);
    ?>

配列への代入においては、常に値がコピーされることに注意してください。 配列をリファレンスでコピーする場合には、 リファレンス演算子を使う必要があります。

例31 配列のコピー

    <?php
    $arr1 = array(2, 3);
    $arr2 = $arr1;
    $arr2[] = 4; // $arr2 が変更されます。
                 // $arr1 は array(2,3) のままです。

    $arr3 = &$arr1;
    $arr3[] = 4; // $arr1 と $arr3 は同じ内容になります。

    var_dump($arr1, $arr2, $arr3);
    ?>

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open