LoginSignup
4
6

More than 5 years have passed since last update.

【PHP】とりあえずAPIのスタブをパパっと作る(JSONリクエスト版)

Last updated at Posted at 2018-02-15

今度はJSONを受け取ってくれるAPIのスタブつくろう

【PHP】とりあえずAPIのスタブをパパっと作る では単純なPOSTを受け取るAPIは作ったんですが、
世の中にはJSONを受け取るAPIも存在するようで。
必要ならばつくらねばならない。めんどくさいが

スタブAPI(JSONリクエスト版)

このPHPファイルを仮サーバーにおいてこいつと通信する。
例ではPOSTパラメータは{"json":{"name":"*****"}}nameを受け取って、その値に対して'_RECEIVED'を付加して、時間とともにjsonにして返す
てな感じの処理をしてます。(APIのスタブとほぼ同じ
また、受け取ったlogも出力するようにしてます。

api-json.php
// header('Access-Control-Allow-Origin: *'); // どこからでもアクセス許可するならワイルドカード
header('Access-Control-Allow-Origin: https://*******/post.php'); // 厳密なURL指定
header('Access-Control-Allow-Credentials: true'); // Basic認証やCookieのやり取りする際は必要(ワイルドカード使用すると使えない)
header('Access-Control-Allow-Headers: Content-Type');
header('Content-Type: application/json; charset=utf-8');

date_default_timezone_set('Asia/Tokyo');

// 設置するサーバーでfile_get_contents使えんかったら動かないです
$jsonParams = file_get_contents('php://input');

// 直後のIF文でエラーをキャッチする為の仮デコード処理
json_decode($jsonParams, true);

if(json_last_error() !== JSON_ERROR_NONE || strlen($jsonParams) <= 0) {

    $jsonArray['json']['name'] = '(JSON_DECODE_ERROR)';

} else {

    $jsonArray = json_decode($jsonParams, true);

    if (isset($jsonArray['json']) === true &&$jsonArray['json'] !== '') {
        if (isset($jsonArray['json']['name']) === false || $jsonArray['json']['name'] === '') {
            $jsonArray['json']['name'] = '(KEY_OR_VALUE_OF_NAME_IS_NOT_EXISIST)';
        }
    } else {
        $jsonArray['json']['name'] = '(KEY_OF_JSON_IS_NOT_EXISIST)';
    }

}

// API側で受け取ったよというマーク的なやつを付加
$name = htmlspecialchars($jsonArray['json']['name'], ENT_QUOTES) . '_RECEIVED';

$array = [
    'json' => [
        'name' => $name,
        'date' => date("Y-m-d H:i:s"),
    ]
];

$json = json_encode($array);

/* log出力 */
$file = new SplFileObject('api-json_log.txt', 'a');
$file->fwrite(
    "【→API】RequestParameter:" . $jsonParams . "\n【←API】ReturnParameter :" . $json . "\n----------\n"
);

echo $json;
exit;

logファイルにはリクエストパラメータと返すパラメータの両方を出力するようにしています。

api-json_log.txt
【→API】RequestParameter:{"json":{"name":"POST_JSON_BY_FORM"}}
【←API】ReturnParameter :{"json":{"name":"POST_JSON_BY_FORM_RECEIVED","date":"2018-02-15 16:40:30"}}
----------
【→API】RequestParameter:{"json":{"name":"POST_JSON_BY_FORM"}}
【←API】ReturnParameter :{"json":{"name":"POST_JSON_BY_FORM_RECEIVED","date":"2018-02-15 17:08:29"}}
----------

【→API】 とか 【←API】見やすくないですか?あ、そうでもないですか・・・

JSONをPOSTする側の実装

post.php
/**
 * APIに対してJSONをPOST送信し返り値を取得する
 *
 * @param string $url
 * @param array $postParams
 * @return array
 */
function sendPostJsonToApiByCurl($url, $postParams)
{
    $ch = curl_init($url);

    $postOption = [
        CURLOPT_POST           => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS     => json_encode($postParams, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); //JSON へエンコード処理('/'をエスケープしない&日本語をパースしない)
        CURLOPT_RETURNTRANSFER => true,
    ];

    curl_setopt_array($ch, $postOption);

    $content = curl_exec($ch); 
    $err     = curl_errno($ch); 
    $errmsg  = curl_error($ch);
    $header  = curl_getinfo($ch);

    curl_close($ch); // リソース開放

    /* errorチェック */
    if ($err !== 0) {
      if ($errmsg !== '') {
          return ['error' => $errmsg];    
      }
      return [];
    }

    if ($header['http_code'] !== 200) {
        if ($errmsg !== '') {
            return ['error' => $errmsg];
        }
        return ['http_code' => $header['http_code']];
    }

    return json_decode($content, true);
}

おわり

  • 今回もAPI側のheaderの設定箇所で指摘あれば教えてくださいです
  • $postOptionの設定も指摘あれば教えてください
  • 今回も関数名ながくない?もうこれでいいか
  • タイプヒンティング書いてないのはPHP7で動かす想定してないから

参考

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6