PHP で Web API のレスポンスを扱う方法
PHP
Published: 2018-11-25

目的

外部の API を利用して、レスポンスを受け取る時に良い方法はないかと

現時点での考えをまとめました。

やってみる

方法1. 配列で扱う

<?php

// API を実行して、下記のレスポンスを取得するという想定
$json = '[
    {
        "date": "2018-11-12 00:00:00",
        "result": "item1"
    },
    {
        "date": "2018-11-12 11:23:00",
        "result": "item2"
    }
]';

var_dump(json_decode($json, true)) . "\n";

出力

array(2) {
  [0]=>
  array(2) {
    ["date"]=>
    string(19) "2018-11-12 00:00:00"
    ["result"]=>
    string(5) "item1"
  }
  [1]=>
  array(2) {
    ["date"]=>
    string(19) "2018-11-12 11:23:00"
    ["result"]=>
    string(5) "item2"
  }
}

方法2. stdClass で扱う

<?php

// API を実行して、下記のレスポンスを取得するという想定
$json = '[
    {
        "date": "2018-11-12 00:00:00",
        "result": "item1"
    },
    {
        "date": "2018-11-12 11:23:00",
        "result": "item2"
    }
]';

var_dump(json_decode($json)) . "\n";

出力

array(2) {
  [0]=>
  object(stdClass)#1 (2) {
    ["date"]=>
    string(19) "2018-11-12 00:00:00"
    ["result"]=>
    string(5) "item1"
  }
  [1]=>
  object(stdClass)#2 (2) {
    ["date"]=>
    string(19) "2018-11-12 11:23:00"
    ["result"]=>
    string(5) "item2"
  }
}

方法3. 独自のクラスにセットする

方法1、方法2ともに API の仕様が変わると意図しない動作をする可能性があります。

外部 API を利用している場合は、自作のクラスで API のレスポンスを入れるのが良いかもしれません。

<?php

// API を実行して、下記のレスポンスを取得するという想定
$json = '[
    {
        "date": "2018-11-12 00:00:00",
        "result": "item1"
    },
    {
        "date": "2018-11-12 11:23:00",
        "result": "item2"
    }
]';

class Item
{
    private $date;
    private $result;

    public function __construct($data)
    {
        $this->date = !isset($data['date']) ?: $data['date'];
        $this->result = !isset($data['result']) ?: $data['result'];
    }
}

class ItemCollection extends ArrayObject
{
    public function offsetSet($offset, $value)
    {
        if (!is_object($value) || get_class($value) !== 'Item') {
            throw new InvalidArgumentException;
        }
        return parent::offsetSet($offset, $value);
    }
}

$rows = json_decode($json, true);

$data = new ItemCollection();

foreach ($rows as $row) {
    $item = new Item($row);
    $data[] = $item;
}

var_dump($data);

出力

object(ItemCollection)#1 (1) {
  ["storage":"ArrayObject":private]=>
  array(2) {
    [0]=>
    object(Item)#2 (2) {
      ["date":"Item":private]=>
      string(19) "2018-11-12 00:00:00"
      ["result":"Item":private]=>
      string(5) "item1"
    }
    [1]=>
    object(Item)#3 (2) {
      ["date":"Item":private]=>
      string(19) "2018-11-12 11:23:00"
      ["result":"Item":private]=>
      string(5) "item2"
    }
  }
}

データ構造を固定できました。

参考