[PHP 初学] 配列とオブジェクトの違いについて「完全に理解した」状態にする

この記事は [株式会社サイバー・バズ Advent calendar 2021](https://qiita.com/advent-calendar/2021/cyberbuzz) 13日目の記事です。

11日目の記事は [GoogleAppsScript(GAS)で効率化する時になんだかんだよく使うコードスニペット10選](https://qiita.com/kashira2339/items/d0e399a97bf586132ea1)  、
14日目の記事は [マイクロサービスアーキテクチャにおけるProtocolBuffers管理のGitHubActionsフローを実現した](https://qiita.com/Hirochon/items/1aab7ff0dab5a1159659) です。

---

**PHP 初学者向け**の記事です。

本記事では**「配列とオブジェクトを完全に理解した」状態**になるため必要な

- **PHP における配列とオブジェクト**がなんなのか
- それぞれの**値の取り出し方**

についてまとめました。

# 配列

**複数の値**をまとめて管理することのできる**型**です。

```php
array([値1], [値2], ...)
```

で作成することができます。

以下の説明では「車」を例として扱います。
引用元：[自動車はどんな部品で構成されているのですか？ | JAF](https://jaf.or.jp/common/kuruma-qa/category-construction/subcategory-structure/faq071)

車を構成する要素

- body
- chassis
- engine
- drivetrain

の4つを持つ配列`$car`を宣言します。

```php:入力
<?php
$car = array(
    'body',
    'chassis',
    'engine',
    'drivetrain',
);
```

`body`, `chassis`, `engine`, `drivetrain`, が配列`$car`の**値**になります。

このとき`var_dump($car)`の出力結果は、

```console:出力
array(4) {
  [0]=>
  string(4) "body"
  [1]=>
  string(7) "chassis"
  [2]=>
  string(6) "engine"
  [3]=>
  string(10) "drivetrain"
}
```

となります。
配列 `$car` には

* 0番目に`body`
* 1番目に`chassis`
* 2番目に`engine`
* 3番目に`drivetrain`

の値が格納されています。

### 特定の値の取り出し方

**「0番目の値を取り出したい！」**という時には

```php
$car[0]
```

と、配列の後ろで`[0]`のように番号指定することによって

```console:0番目のvar_dump出力
string(4) "body"
```

特定の値を取り出すことができます。

## 連想配列

先述した配列を扱いやすく宣言したものです。

```php:入力
<?php
$car = array(
    'body'          => 'ボンネットやトランクリッド',
    'chassis'       => '足回り関連',
    'engine'        => 'エンジン',
    'drivetrain'    => '駆動系部品',
);
```

この場合、
`ボンネットやトランクリッド`, `足回り関連`, `エンジン`, `駆動系部品`, が連想配列`$car`の値で、
`body`, `chassis`, `engine`, `drivetrain`, は連想配列`$car`の**キー**と呼びます。

このとき`var_dump($car)`の出力結果は、

```console:出力
array(4) {
  ["body"]=>
  string(39) "ボンネットやトランクリッド"
  ["chassis"]=>
  string(15) "足回り関連"
  ["engine"]=>
  string(12) "エンジン"
  ["drivetrain"]=>
  string(15) "駆動系部品"
}
```

となります。
連想配列 `$car` には

* キー`body` に　`ボンネットやトランクリッド`
* キー`chassis` に　`足回り関連`
* キー`engine` に　`エンジン`
* キー`drivetrain` に　`駆動系部品`

が格納されています。

### 特定の値の取り出し方

連想配列では、**キー**によって取り出す値を指定します。

**「キー`body`の値を取り出したい！」**という時には

```php
$car['body']
```

と、配列の後ろでキーを指定することによって

```console:キーbodyのvar_dump出力
string(39) "ボンネットやトランクリッド"
```

特定の値を取り出すことができます。

## 多次元配列

**ネストされた配列**（配列、連想配列が入れ子になっているもの）のことです。

```php:入力
<?php
$car = array(
    'chassis'       => array(
        'suspension'    => 'サスペンション',
        'steering'      => 'ステアリング',
        'tire'          => 'タイヤ',
        'wheel'         => 'ホイール',
    ),
    'drivetrain'    => array(
        'transmission'  => 'トランスミッション',
        'driveshaft'    => 'ドライブシャフト',
        'differential'  => 'デファレンシャル',
    ),
);
```

`var_dump($car)`の出力結果は、

```console:出力
array(2) {
  ["chassis"]=>
  array(4) {
    ["suspension"]=>
    string(21) "サスペンション"
    ["steering"]=>
    string(18) "ステアリング"
    ["tire"]=>
    string(9) "タイヤ"
    ["wheel"]=>
    string(12) "ホイール"
  }
  ["drivetrain"]=>
  array(3) {
    ["transmission"]=>
    string(27) "トランスミッション"
    ["driveshaft"]=>
    string(24) "ドライブシャフト"
    ["differential"]=>
    string(24) "デファレンシャル"
  }
}
```

となります。

### 特定の値の取り出し方

ファイルのディレクトリのように、キーを続けて記述することで取り出すことができます。
たとえば、

```php
$car['drivetrain']['transmission']
```

と指定した場合は

```console:var_dump出力
string(27) "トランスミッション"
```

の値を取り出すことができます。

# オブジェクト

オブジェクトを生成するためには、まず**クラス**を宣言する必要があります。
宣言方法は、

```php
class クラス名
{
    [クラスの中身]
}
```

です。車の例を使って実際に宣言してみます。

```php:入力
<?php
class Car
{
    public $body          = 'ボンネットやトランクリッド';
    public $chassis       = '足回り関連';
    public $engine        = 'エンジン';
    public $drivetrain    = '駆動系部品';
}
```

書き方がかなり変わりました。

ここの `$body` `$chassis` 等は**プロパティ**と呼ばれます。

<details>
<summary>気になる人向け：`public`とは？</summary>
アクセス修飾子です。そのプロパティ等がどこからアクセス可能化を表します。
他に `private` `protected` があります。
</details>

では `Car` を出力してみましょう。

`Car` をオブジェクトとして出力するには**`new`演算子を用いてインスタンス化**する必要があります。

```php:インスタンス化
$car = new Car();
```

これで　`$car`　を生成できました。
`var_dump($car)`の出力結果は、

```console:出力
object(Car)#1 (4) {
  ["body"]=>
  string(39) "ボンネットやトランクリッド"
  ["chassis"]=>
  string(15) "足回り関連"
  ["engine"]=>
  string(12) "エンジン"
  ["drivetrain"]=>
  string(15) "駆動系部品"
}
```

となります。
出力の形が連想配列と似ていますね。

### 特定の値の取り出し方

オブジェクトから特定の値を取り出す方法は、配列と異なります。
出力形が連想配列と似ていますが、**キーの指定による出力はできません**。
（オブジェクトにはキーが存在しないため）

オブジェクトの場合は**プロパティ**にアクセスし、値を取り出します。

**「プロパティ`$body`の値を取り出したい！」**という時には

```php
$car->body
```

**`->`** という**アロー演算子** を用いてアクセスします。

`var_dump($car->body)` の出力結果は

```console:var_dump出力
string(39) "ボンネットやトランクリッド"
```

となります。

# まとめ

最初は混乱しがちな配列とオブジェクトについて基本をおさらいしてみました。

PHP を初めたばかりの方は、

- **配列→キーを用いて取り出す**
- **オブジェクト→アロー演算子を用いてプロパティにアクセスし、取り出す**

と、**値の取り出し方が違うこと**を意識しておくと良いかと思います。

また、型の確認漏れを防ぐには**`var_dump`を用いて`array`なのか`object`なのかをチェックする**ことがオススメです。

今回記載した他にも、オブジェクトの場合は**クラス内でメソッドが記述出来る**などの大きな違いがあります。
配列とオブジェクトの取り扱いに慣れてきた方は、そちらをおさえると一歩前に進めると思います。

## 参考

- [小川雄大，柄沢聡太郎，橋口誠「パーフェクトPHP」（技術評論社、2010年）](https://gihyo.jp/book/2010/978-4-7741-4437-5)
- [PHP: 配列 - Manual](https://www.php.net/manual/ja/language.types.array.php)
- [PHP: クラスの基礎 - Manual](https://www.php.net/manual/ja/language.oop5.basic.php)
- [PHP: オブジェクト - Manual](https://www.php.net/manual/ja/language.types.object.php)
- [【PHP】オブジェクトを連想配列に変換する方法まとめ - Qiita](https://qiita.com/ymm1x/items/f197ddd327356b1e9088)
- [【PHP】オブジェクトと連想配列の違い - Qiita](https://qiita.com/shin_moto/items/7dc3cf0a64738f7a4d6b)
- [配列とオブジェクトの違いについて - Qiita](https://qiita.com/yyy752/items/4216285da17cc9ee07bd)
- [【PHP】クラスの基本 | インスタンス | プロパティとメソッド | オブジェクト指向 - Qiita](【PHP】クラスの基本 | インスタンス | プロパティとメソッド | オブジェクト指向)
- [【PHP】オブジェクトと連想配列の違いについて調べてみた【初心者向け】 | もんプロ～問題発見と解決のためのプログラミング〜](https://coinbaby8.com/different-between-object-and-array.html)