PHPにおける配列:同種のデータをまとめて扱うためのしくみ

2015年2月25日(水)
野田 貴子

はじめに

これから始めるPHP入門コラムでは、PHPを学ぶ人が、PHPで簡単なプログラムを書けるようになるまでに必要な知識とポイントをTips的に書いていきます。今後PHPのスキルを身につけて仕事に役立てたい、という方のために「PHP技術者認定初級試験」の出題範囲を意識しながら進めていきますので、ぜひ最後までお付き合いください。

今回のあらすじ

  1. 数値配列
  2. 連想配列
  3. 配列への要素の追加
  4. 配列の要素の更新
  5. 配列の要素の削除
  6. 配列をループする
  7. 多重配列
  8. 文字列から配列に変換する
  9. 配列から文字列に変換する
  10. 配列操作関数

配列とは

配列とは、データの集まりのことです。PHPで配列を宣言するにはarrayという関数を使います。例えば家族の名前を配列に入れてみると、このようになります。

$myFamily = array("チチ", "ハハ", "タロウ");

PHP5.4以降では他の言語の書式を導入して、以下のようにも書けるようになりました。

$myFamily = ["チチ", "ハハ", "タロウ"];

このコラムではarray()の方で進めていきます。

数値配列

上記の$myFamilyという変数には、3つの要素を含む配列が代入されました。var_dump関数を使って、この変数の中身がどうなっているのか見てみましょう。

var_dump($myFamily);
// array(3) {
//   [0]=>
//   string(6) "チチ"
//   [1]=>
//   string(6) "ハハ"
//   [2]=>
//   string(9) "タロウ"
// }

それぞれの要素には番号が振られていますよね。これらの番号は、各要素を参照するときに使います。

echo $myFamily[0];
// チチ

プログラミングの世界では、番号は0から振られることが一般的で、PHPの配列も0から始まります。この番号のことを「key(添え字)」と呼びます。keyは数値、文字列のどちらも使えます。またkeyに対応する要素を「value(値)」といいます。valueには数値や文字列以外にも、bool値、null値、配列、オブジェクトなどを使うことができます。

配列を作る際に、keyは任意に設定することができます。この場合、各要素は入力した順番に並ぶため、0から順番に並ぶとは限りません。

$myFamily = array(
    1 => "チチ",
    2 => "ハハ",
    0 => "タロウ"
);

var_dump($myFamily);
// array(3) {
//   [1]=>
//   string(6) "チチ"
//   [2]=>
//   string(6) "ハハ"
//   [0]=>
//   string(9) "タロウ"
// }

以上のように、keyに数値だけを使用した配列を「数値配列」と呼びます。

連想配列

一方、keyに文字列を使った配列は「連想配列」といいます。

$myFamily = array(
    "father" => "チチ",
    "mother" => "ハハ",
    "me" => "タロウ"
);

var_dump($myFamily);
// array(3) {
//   ["father"]=>
//   string(6) "チチ"
//   ["mother"]=>
//   string(6) "ハハ"
//   ["me"]=>
//   string(9) "タロウ"
// }

上の例の場合、$myFamily[0]に対応するもの(値)はありません。

echo $myFamily[0];
// (NULLなので何も出力されない)
echo $myFamily["me"];
// タロウ

配列に要素を追加する

あとから配列に要素を追加する場合、添え字を空にした[]を使うと、現在の配列の大きさを意識することなく、配列の最後に新しい要素を追加できます。

数値配列

$myFamily = array("チチ", "ハハ", "タロウ");
$myFamily[] = "セブン";

var_dump($myFamily);
// array(4) {
//   [0]=>
//   string(6) "チチ"
//   [1]=>
//   string(6) "ハハ"
//   [2]=>
//   string(9) "タロウ"
//   [3]=>
//   string(9) "セブン"
// }

連想配列

$myFamily = array(
    "father" => "チチ",
    "mother" => "ハハ",
    "me" => "タロウ"
);
$myFamily[] = "セブン";
var_dump($myFamily);

// array(4) {
//   ["father"]=>
//   string(6) "チチ"
//   ["mother"]=>
//   string(6) "ハハ"
//   ["me"]=>
//   string(9) "タロウ"
//   [0]=>
//   string(9) "セブン"
// }

どちらの場合も、あとから追加した「セブン」に一番大きい番号のkey(文字列のkeyは対象外)が割り当てられています。

keyに数値(0、1など)を指定せずに、数値文字列('0'、"1"など)を指定した場合、そのkeyは自動的に数値に変換されます。

連想配列

$myFamily = array(
    "father" => "チチ",
    "mother" => "ハハ",
    "0" => "タロウ"
);
$myFamily[] = "セブン";
var_dump($myFamily);

// array(4) {
//   ["father"]=>
//   string(6) "チチ"
//   ["mother"]=>
//   string(6) "ハハ"
//   [0]=>
//   string(9) "タロウ"
//   [1]=>
//   string(9) "セブン"
// }

配列のkeyを指定する

keyを指定するには以下のように指定します。1つの配列内で数値と文字列のkeyを併用することもできます。ただし、混在させない方が理解しやすいコードになります。

$myFamily = array("チチ", "ハハ", "タロウ");
$myFamily[10] = "セブン";
$myFamily['brother'] = "ギンガ";

var_dump($myFamily);
// array(4) {
//   [0]=>
//   string(6) "チチ"
//   [1]=>
//   string(6) "ハハ"
//   [2]=>
//   string(9) "タロウ"
//   [10]=>
//   string(9) "セブン"
//   ["brother"]=>
//   string(9) "ギンガ"
// }

配列の要素の更新

すでに同名のkeyがある場合に、新たに値を設定すると、値は上書きされます。

$myFamily[2] = "ジロウ";

var_dump($myFamily);
// array(4) {
//   [0]=>
//   string(6) "父"
//   [1]=>
//   string(6) "ハハ"
//   [2]=>
//   string(9) "ジロウ"
//   [10]=>
//   string(9) "セブン"
//   ["brother"]=>
//   string(9) "ギンガ"
// }

配列の要素の削除

要素を削除するには、unset関数を使います。

$myFamily = array(
    "father" => "チチ",
    "mother" => "ハハ",
    "me" => "タロウ"
);
unset($myFamily["me"]);
var_dump($myFamily);

// array(2) {
//   ["father"]=>
//   string(6) "チチ"
//   ["mother"]=>
//   string(6) "ハハ"
// }

配列内の要素をまとめて処理する

配列を使う利点は、配列に入っている要素すべてに対して同じ処理ができることです。そのためには、配列をループして、すべての要素を1つずつ参照します。

for文のループ

数値配列の場合、前回取り上げたfor文のループを使うことができます。配列の長さは count 関数で求めることができます。

$myFamily  = array("チチ", "ハハ", "タロウ");
$length = count($myFamily);
for($i = 0; $i < $length; $i++) {
        echo "{$i}番目の名前は{$myFamily[$i]}です。\n";
}

// 0番目の名前はチチです。
// 1番目の名前はハハです。
// 2番目の名前はタロウです。

foreach文のループ

foreach文は、数値配列と連想配列のどちらにも使用できます。配列の長さを事前に求める必要はありません。

数値配列

$myFamily  = array("チチ", "ハハ", "タロウ");
foreach($myFamily as $key => $val) {
        echo "{$key}番目の名前は{$val}です。\n";
}

// 0番目の名前はチチです。
// 1番目の名前はハハです。
// 2番目の名前はタロウです。

$keyを使わない場合は、「foreach($myFamily as $val)」と省略して書くことができます。$val には $myFamily [$key] の値が入ります。例で使用した$keyや$valという変数名は任意に変更することができますので、分かりやすい名前を使うとよいでしょう。

連想配列

$myFamily = array(
    "father" => "チチ",
    "mother" => "ハハ",
    "me" => "タロウ"
);
foreach($myFamily as $relationship => $name) {
        echo "{$relationship}の名前は{$name}です。\n";
}

// fatherの名前はチチです。
// motherの名前はハハです。
// meの名前はタロウです。

ループ内で元の値を更新するとどうなるか

ループ中で値を参照しているだけ変数である$valなどを変更しても、元の配列には反映されません。

$myFamily  = array("チチ", "ハハ", "タロウ");
foreach($myFamily  as $val) {
        $val .= "ちゃん";
        echo "{$val}です。\n";
}

// チチちゃんです。
// ハハちゃんです。
// タロウちゃんです。

var_dump($myFamily);

// array(3) {
//   [0]=>
//   string(6) "チチ"
//   [1]=>
//   string(6) "ハハ"
//   [2]=>
//   string(9) "タロウ"
// }

元の配列を更新するためには、以下の例のようにループしている配列そのものの$myFamilyを更新します。

$myFamily  = array("チチ", "ハハ", "タロウ");
foreach($myFamily  as $key => $val) {
        $myFamily[$key] .= "ちゃん";
}
var_dump($myFamily);

// array(3) {
//   [0]=>
//   string(15) "チチちゃん"
//   [1]=>
//   string(15) "ハハちゃん"
//   [2]=>
//   string(18) "タロウちゃん"
// }

多重配列

配列の中には、さらに配列を入れることもできます。こうすることで、何段階でも配列の階層を深くすることができます。

$me = array(
        "name" => "タロウ",
        "age" => 50
);
$son = array(
        "name" => "ジロウ",
        "age" => 25
);
$daughter = array(
        "name" => "ハナコ",
        "age" => 20
);
$me["children"] = array($son, $daughter);

var_dump($me);
// array(3) {
//   ["name"]=>
//   string(9) "タロウ"
//   ["age"]=>
//   int(50)
//   ["children"]=>
//   array(2) {
//     [0]=>
//     array(2) {
//       ["name"]=>
//       string(9) "ジロウ"
//       ["age"]=>
//       int(25)
//     }
//     [1]=>
//     array(2) {
//       ["name"]=>
//       string(9) "ハナコ"
//       ["age"]=>
//       int(20)
//     }
//   }
// }

多重配列内のデータを扱うためには、for文やforeach文などのループ文も多重にします。

foreach($me as $key => $val) {
    echo "{$key} は {$val} です。\n";
    if ($key === "children") {
        foreach($val as $ckey => $cval) {
            echo "{$ckey} 人目の子供の名前は {$cval['name']} です。\n";
        }
    }
}

// name は タロウ です。
// age は 50 です。
// children は Array です。
//(配列を echo すると「Array」が出力されます)
// 0 人目の子供の名前は ジロウ です。
// 1 人目の子供の名前は ハナコ です。

文字列から配列に変換する

文字列を配列に変換する用途は、たくさんあります。例えばURLのパラメータで指定されたカンマ区切りのカテゴリーID(&cat="a,b,c" の "a,b,c" の部分など)を、配列に入れると array("a", "b", "c") のようになり、プログラムで扱いやすくなります。文字列全体を配列の1つの要素に変換するためには、その文字列を「array(」と「)」で囲います。

$string = "あかんぼあかいなあいうえお";
$array = array($string);

var_dump($array);
// array(1) {
//   [0]=>
//   string(39) "あかんぼあかいなあいうえお"
// }

文字列を区切り文字で区切って配列に変換するためには、explode関数を使います。第一引数(",")に区切り文字を、第二引数には分割したい文字列($colors)を指定します。

$colors = "赤,青,緑";
$arColors = explode(",", $colors);

var_dump($arColors);
// array(3) {
//   [0]=>
//   string(3) "赤"
//   [1]=>
//   string(3) "青"
//   [2]=>
//   string(3) "緑"
// }

foreach($arColors as $val) {
        // 配列になったのでループもできます
}

explode 関数には第三引数もあり、いろいろな分割方法を指定できます。以下に例を挙げますが、詳しくはドキュメントを参照してください。

// 第三引数に正数を指定すると、その個数に分割されます
$phone = "03-1234-5678";
var_dump(explode("-", $phone, 2));
// array(2) {
//   [0]=>
//   string(2) "03"
//   [1]=>
//   string(9) "1234-5678"
// }
// 第三引数に負数を指定すると、引数を正数にした個数の要素が最後から切り捨てられます
$filename = "example.tmp.exe";
var_dump(explode(".", $filename, -1));
// array(2) {
//   [0]=>
//   string(7) "example"
//   [1]=>
//   string(3) "tmp"
// }

配列から文字列に変換する

今度は逆に配列から文字列に変換する方法です。配列で処理をした後に、URLのパラメータに書き出したり、ファイルに出力したりするのに使えます。こちらはimplode関数を使います。

$arParams = array("year=2014", "month=12", "day=25");
$params = implode("&", $arParams);

var_dump($params);
// string(25) "year=2014&month=12&day=25"

その他の配列操作関数

上記で紹介した以外にも配列を操作する関数は山ほどありますので、「こういう処理をしたいな」と思ったら、とりあえずドキュメントを調べてみるとよいでしょう。以下はほんの一例です。

array_key_exists

配列の中に指定したキーが存在するかどうかを調べます。キーの有無によって、その後の処理を変えたい場合に使います。

if (array_key_exists("father", $arFamily)) {
        // $arFamily["father"] があるならtrue
}

in_array

ある値が、配列の中にあるあるかどうかを調べます。

if (in_array("味噌汁", $arDinner)) {
        // $arDinner[キーは不問] == "味噌汁" ならtrue
}

「in_array("味噌汁", $arDinner, true)」のように第三引数に「true」を指定すると、「==」 ではなく「===」での判定になります。

array_search

配列の中に指定した値があれば、対応するキーを返します。複数の要素にヒットした場合は、最初に見つかったものを返します。第三引数は型の等しさもチェックするかどうかで、デフォルトではOFF(false)になっています。

$arScores = array(
        "チチ" => 120,
        "ハハ" => 120,
        "タロウ" => "120"
);
var_dump(array_search("120", $arScores));
// string(6) "チチ"
var_dump(array_search("120", $arScores, true));
// string(9) "タロウ"
var_dump(array_search("100", $arScores));
// bool(false)

配列のソート関数

配列内の要素を並び替える関数もたくさんあります。それぞれ特徴がありますので、ソート関数の比較や各ソート関数のドキュメントを読んでみてください。普通にソートすると数値順やアルファベット順になりますが、自作の関数を使って特殊な並び順でソートすることもできます。例えば住所による五十音順ではないソート(XYZ区はABC区よりも前、など)ができます。

sort普通にソートする
rsort逆順にソートする
ksortキーでソートする
krsortキーで逆順にソートする
asort連想キーと要素との関係を維持しつつソートする
arsort連想キーと要素との関係を維持しつつ逆順にソートする
usortユーザー定義の比較関数を使用して、値でソートする
uksortユーザー定義の比較関数を用いて、キーでソートする
uasortユーザー定義の比較関数でソートし、連想インデックスを保持する

おわりに

いかがでしたか? 覚えることがたくさんありそうですが、PHPでは配列を使わないプログラムはないくらいに配列をよく利用しますので、きっとすぐに慣れると思いますよ。それではまた。

1983年生まれ。大学卒業後、ソフトウェア開発の営業を経て、ソフトウェア開発業務に転向。現在は自社パッケージのフロントエンド開発のほか、PHPでの受託開発案件、日→英のローカライズ案件などを担当。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています