PHP PHP入門講座 プログラミング

【PHPプログラミング入門講座】連想配列

PHPプログラミングのキービジュアル

一般的な配列

前の記事「【PHPプログラミング入門講座】配列とループ処理 (foreach文)」で、配列について説明しました。
以下にこれまでの記事に登場した配列の例をいくつか書きます。

$priceList = [110, 90, 80, 100, 60];

$wdayJapanese= ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'];

$list= ['O', 'R', 'V', 'I', 'N', 'U', 'M', 'X', 'C', 'G'];

これらの配列に共通する特徴は、全ての要素が同じ種類の値であるということです。

具体的には、
1番目はデータ型が数値型であり、値段を表している要素の配列。
2番目はデータ型が文字列型で、曜日を表している要素の配列。
3番目はデータ型が文字列型であり、アルファベット1文字の要素の配列。
です。

そして、これらのような全ての要素が同じ種類の値である配列は、foreach文、for文、while文、do-while文などのループ処理を使って、各要素に対して同じ処理をするのに適しています。

各要素の種類が異なる配列

PHPの配列の要素は全て同じ種類でなくても問題なく使用することができます。
例えば、次のような使い方ができます。

<?php
  $list = ['山田太郎', '男性', 20, '2000/1/1', 170];
 
  echo '氏名:' . $list[0] . '<br>';
  echo '性別:' . $list[1] . '<br>';
  echo '年齢:' . $list[2] . '歳<br>';
  echo '生年月日:' . $list[3] . '生まれ<br>';
  echo '身長:' . $list[4] . 'cm<br>';

このサンプルプログラムでは、配列の要素が前から順に氏名、性別、年齢、生年月日、身長となっており、各要素のデータ型も内容も異なります。
このような配列の各要素のデータの内容が異なるような使い方をしてもOKです。
実行結果は次のようになります。

氏名:山田太郎
性別:男性
年齢:20歳
生年月日:2000/1/1生まれ
身長:170cm

ただ、この書き方の場合、次のような点に注意する必要があります。

  • 配列のどのインデックス 番号が何を表す値であるかを覚えておく必要がある。
  • 配列の要素が追加された場合に、挿入された要素より後ろにある要素のインデックス 番号が全て1つずつ後ろにずれる。
    (例) 氏名「山田太郎」の後ろにフリガナ「ヤマダタロウ」が追加された場合
    $list = ['山田太郎', 'ヤマダタロウ', '男性', 20, '2000/1/1', 170];
    この場合、フリガナ「ヤマダタロウ」のインデックス 番号1になり、それ以降の全要素のインデックス 番号が1ずつ後ろにずれます。

要素を途中に追加したらインデックス 番号がずれてしまう配列を使って、常にインデックス 番号と値の対応を管理するのは不可能です。

このような場合に使うと便利なのが「連想配列」です。

連想配列

連想配列とは、「キー」と「値」の組み合わせを保持する配列のことです。
配列は「インデックス 番号」で要素を指定しますが、連想配列は「キー」(文字列)で要素を指定します。

「キー」とは、配列内の各要素を一意に指定するための文字列のことです。

具体的に配列と連想配列の書き方の違いについて説明します。
配列は次のように値を並べて書きます。

$list = ['山田太郎', '男性', 20, '2000/1/1', 170];

連想配列は、次のようにキーと値のセットを並べて書きます。

$list = ['name' => '山田太郎', 'gender' => '男性', 'age' => 20, 'birthday' => '2000/1/1', 'height' => 170];

この例では、name、gender、age、birthday、heightが「キー」であり、山田太郎、男性、20、2000/1/1、170が「値」になります。
連想配列の一つの要素は「'キー' => 値」の形でセットになっており、セットが複数ある場合はカンマ「,」で区切って書きます。
「=>」は、キーと値の対応を示すPHPの記述方法です (演算子ではありません)。
なお、キーの値は自由に決めてOKです。ただし、対象の連想配列の中で同じキーを複数指定しないよう注意してください。
同じキーの要素が複数ある場合、前側にある要素は、同じキーの最後の要素に上書きされます。

ところで、この連想配列を1行で書きましたが、ちょっと読みづらいですよね?
次のように、キーと値のセットで1行ずつ書くと読みやすくなります。

$map = [
  'name' => '山田太郎',
  'gender' => '男性',
  'age' => 20,
  'birthday' => '2000/1/1',
  'height' => 170
];

連想配列を代入する変数名は、ここでは$mapにしていますが、変数名は自由に決めてOKです。

連想配列の値を初期化する場合は、このようにキーと値の組み合わせ1セットにつき1行に書くのが一般的です。
読みやすいプログラムになるように心がけましょう。

ところで、上記のように、連想配列の値を一括で代入するのではなく、個別で代入したい場合は、次のように書くことができます。

$map = [];
$map['name'] = '山田太郎';
$map['gender'] = '男性';
$map['age'] = 20;
$map['birthday'] = '2000/1/1';
$map['height'] = 170;

これで、キー「name」に対して値「山田太郎」を代入、キー「gender」に対して値「男性」を代入、、、という処理をすることができます。

ここで注意して欲しいのは、個別でキーに対する値を代入する場合は「=>」ではなく、代入演算子「=」を使うという点です。
初めての時は、「=>」と「=」を書き間違えやすいので注意しましょう。

では、この処理の説明をします。
最初の「 $map = [ ]; 」では、変数$mapを空配列で初期化しています。
空配列とは要素が一つも存在しない配列のことです。
この初期化は、この処理がプログラムの一部であった場合に、もしすでに変数$mapが使われていたら、その値が残ったままになることがあるため、変数$listの値をリセットしておくための処理です。
バグが発生しにくいプログラムを書くためには、初期化をキチンとすることは重要です。覚えておきましょう。

その次に、キー「name」に対する値に「山田太郎」を代入、キー「gender」に対する値に「男性」を代入、、、というように個別で要素に値を代入しています。
このように連想配列のある一つのキーに対する値を代入する場合は、「 $map['キー'] = 値; 」という形で書きます。

つまり、配列は添字にインデックス 番号を書きますが、連想配列はキー(文字列)を書きます。

連想配列の値の参照

先ほどは、連想配列に値を代入する方法について説明しました。
次は、連想配列に代入された値を参照する方法について説明します。

値の代入と、値の参照の関係が分かるよう、連想配列に値を代入した後に、その値を参照するサンプルプログラムを書きます。

<サンプルプログラム>

<?php
  //値の代入
  $map = [
    'name' => '山田太郎'
  ];

  //キー「name」の値を参照して、echoで出力。
  echo $map['name'];

なお、次のように書いても、同じ処理です。

<?php
  //初期化
  $map = [];
  //値の代入
  $map['name'] = '山田太郎';

  //キー「name」の値を参照(取得)して、echoで出力。
  echo $map['name'];

最初に、連想配列$mapのキー「name」に対して、値「山田太郎」を代入しています。
その後、キー「name」の値は、$map['name']で参照できます。

このサンプルプログラムの実行結果は次のようになります。

<実行結果>

山田太郎

連想配列のサンプルプログラム

以上で、連想配列の値の代入と値の参照について説明しましたので、次は連想配列のいろいろな書き方について説明します。

サンプルプログラム1 (連想配列を変数に代入)

先ほどは、連想配列の要素を直接echoで出力するサンプルプログラムを書きましたが、変数に代入することもできます。

<?php
  $map = [
    'name' => '山田太郎'
  ];

  //キー「name」の値を変数$nameに代入
  $name = $map['name'];

  echo $name . '<br>';

「 $name = $map['name']; 」の処理で、連想配列$mapのキー「name」の値を、変数$nameに代入しています。
なお、$nameは単体の変数であり、$map['name']は連想配列の中のキー「name」の値です。
これらは全く別モノであり、互いに影響されて値が書き変わることはありません。
このプログラムの実行結果は次の通りです。

<実行結果>

山田太郎

サンプルプログラム2 (連想配列の値の変更)

一度、連想配列に代入した値は、後から変更することができます。

<?php
  $map = [
    'name' => '山田太郎',
    'age' => 20,
    'height' => 170
  ];

  //要素の値を変更する
  $map['name'] = '木村次郎';
  $map['age'] = 25;

  echo '氏名:' . $map['name'] . '<br>';
  echo '年齢:' . $map['age'] . '歳<br>';
  echo '身長:' . $map['height'] . 'cm<br>';

<実行結果>

氏名:木村次郎
年齢:25歳
身長:170cm

このサンプルプログラムでは、キー「name」と「age」の値を後から書き換えています。
キー「height」の値は書き換えてないため、最初の値が出力されます。

サンプルプログラム3 (連想配列の要素の追加)

最初に連想配列の要素に存在しないキーに対して値を代入すると、そのキーと値を追加することができます。

<?php
  $map = [
    'name' => '山田太郎',
    'age' => 20,
    'height' => 170
  ];

  //新しい要素を追加する
  $map['weight'] = 65;

  echo '氏名:' . $map['name'] . '<br>';
  echo '年齢:' . $map['age'] . '歳<br>';
  echo '身長:' . $map['height'] . 'cm<br>';
  echo '体重:' . $map['weight'] . 'kg<br>';

<実行結果>

氏名:山田太郎
年齢:20歳
身長:170cm
体重:65kg

このサンプルプログラムでは、最初の連想配列に存在しなかったキー「weight」とその値を後から追加しています。

サンプルプログラム4 (連想配列の全体の上書き)

連想配列$mapに値を代入した後に、再度同じ変数$mapを使って値を代入すると、全ての値が置き換えられます。

<?php
  $map = [
    'name' => '山田太郎',
    'age' => 20,
    'height' => 170
  ];

  $map = [
    'name' => '木村次郎',
    'age' => 25,
  ];

  echo '氏名:' . $map['name'] . '<br>';
  echo '年齢:' . $map['age'] . '歳<br>';
  echo '身長:' . $map['height'] . 'cm<br>';

<実行結果>

氏名:木村次郎
年齢:25歳
身長:cm

2回目の$mapへ連想配列を代入する処理で、最初に代入した$mapがすべて書き換えられます。
2回目に代入した連想配列$mapにはキー「height」の値が設定されていないため、$map['height']の値は空になります。

var_dump関数での出力

記事「【PHPプログラミング入門講座】数値と文字列の性質・デバッグ」で説明した「var_dump関数」を使って連想配列を出力すると、その連想配列の全てのキーと値とデータ型を調べることができます。

<サンプルプログラム>

<?php
  $map = [
    'name' => '山田太郎',
    'gender' => '男性',
    'age' => 20,
    'birthday' => '2000/1/1',
    'height' => 170
  ];

  var_dump($map);

実行結果は次のようになります。
※注:ブラウザで確認する場合は改行されませんので、HTMLソースで確認してください。

<実行結果>

array(5) {
 ["name"]=>
 string(12) "山田太郎"
 ["gender"]=>
 string(6) "男性"
 ["age"]=>
 int(20)
 ["birthday"]=>
 string(8) "2000/1/1"
 ["height"]=>
 int(170)
}

連想配列の各値のデータ型が、数値型の場合はint、文字列型の場合はstringで表示されます。

要素の削除 (unset関数)

連想配列から要素を削除する方法について説明します。

例えば、連想配列$mapの中から、キー「birthday」の要素を削除しようと思い、次のようにプログラムを書いたとします。

<?php
  $map = [
    'name' => '山田太郎',
    'age' => 20,
    'birthday' => '1995/1/1',
    'height' => 170
  ];

  $map['birthday'] = '';

  var_dump($map);

このプログラムを実行すると、次のようになります。

<実行結果>

array(4) {
 ["name"]=>
 string(12) "山田太郎"
 ["age"]=>
 int(20)
 ["birthday"]=>
 string(0) ""
 ["height"]=>
 int(170)
}

キー「birthday」の値は、空文字列になっただけであり、連想配列 $mapの中に残ったままになります。
これではダメです。

連想配列から、指定したキーの要素を完全削除したい場合は「unset関数」を使います。
先ほどのプログラムを次のように修正します。

<?php
  $map = [
    'name' => '山田太郎',
    'age' => 20,
    'birthday' => '1995/1/1',
    'height' => 170
  ];

  unset($map['birthday']);

  var_dump($map);

<実行結果>

array(3) {
 ["name"]=>
 string(12) "山田太郎"
 ["age"]=>
 int(20)
 ["height"]=>
 int(170)
}

これで連想配列$mapからキー「birthday」の要素が削除されました。

シンタックスシュガー (糖衣構文)

PHPの連想配列には、「シンタックスシュガー (糖衣構文)」と呼ばれるものがあります。
シンタックスシュガーとは、プログラミングのしやすさを優先するために、あえてエラーにしない記述方法のことです。

通常は、次のように連想配列の最後の要素の値の「170」の後ろに、要素の区切り記号であるカンマ「,」を書かないのが正式な書き方です。

<?php
  $map = [
    'name' => '山田太郎',
    'age' => 20,
    'height' => 170
  ];

しかし、PHPでは、次のように最後の要素の値「170」の後ろにカンマ「,」を記述してもエラーにはなりませんし、正常にカンマを記述しない場合と同様の動作します。
これが連想配列のシンタックスシュガーです。

<?php
  $map = [
    'name' => '山田太郎',
    'age' => 20,
    'height' => 170,
  ];

シンタックスを活用すると、新しい要素を最後に追加する場合に、今まで最後にあった要素の後ろにカンマ「,」を記述し忘れないように注意を払う必要がなくなります。

<?php
  $map = [
    'name' => '山田太郎',
    'age' => 20,
    'height' => 170,
    'weight' => 60,
  ];

シンタックスシュガーは便利ですので、積極的に活用しましょう。

おわりに

今回は連想配列について、多くのサンプルプログラムを用いながら説明しました。
連想配列は、非常に便利であり、今後PHPでプログラミングをするにあたり、多くの場面で使います。
次の記事に練習問題を用意していますので、自分でプログラムを書きながら練習問題を解いて、理解しておきましょう。

PHPプログラミング入門講座 〜 全記事一覧 〜

-PHP, PHP入門講座, プログラミング
-, , ,

Copyright© ハッピー・プログラミング・ライフ , 2020 All Rights Reserved.