郵便番号から住所を取得するapiでcurlを使っていたところ
もっと今どきでかつセキュリティも高い書き方があると知り、早速そっちを使うことに。
laravel5.8で使用しました。
PHPでApi通信をするためのプラグイン「Guzzle」
Apiだけでもなかなか理解が追いついていないのですが、こういったプラグインを使うことでApi通信をより安全に行うことができるようです。
composer requireをして、(今回は)controller側で呼び出し&Api処理を記述してゆく形になります。
compose require周りの記述はこちらのサイト様をご覧ください。

本番で弾かれる場合はリンクを修正
ローカルで試したところちゃんと動いたのですが、調べてみると本番で動かないことがあるとか。。
その場合は呼び出すurlを以下に修正するといいそうです。
https://zipcloud.ibsnet.co.jp/api/search?zipcode=
controllerに処理を記述
実際にコントローラーに書いた処理内容がこちら
コントローラーの上部でuse
use GuzzleHttp\Client;
以下は処理内容
//zipcodeがあれば市区を取得
$municipalities = '';
if($work['customer']['zipcode']) {
try {
$cZip = $work['customer']['zipcode'];
$cZip = mb_convert_kana($cZip, "na");
$client = new Client();
$url = 'https://zipcloud.ibsnet.co.jp/api/search';
$option = [
'headers' => [
'Accept' => '*/*',
'Content-Type' => 'application/x-www-form-urlencoded'
],
'form_params' => [
'zipcode' => $cZip,
'limit' => 1 //default 20
],
'connect_timeout' => 10, //30とか適当なことが多い。リクエスト先の精度が関係するのでいちがいに言えない
"timeout" => 10
];
$response = $client->request('POST', $url, $option);
$result = json_decode($response->getBody()->getContents(), true);
if($result['status'] !== 200) {
throw new \Exception('ステータスが正常ではありません');
}
$municipalities = $result['results'][0]['address2'];
} catch(\Exception $e) {
//エラー処理
}
}メモ
レスポンスについて
基本エラーだとcatchに入ってくれるのですが、今回使用したzipcloudは検索して住所が見つからない場合に404として返してくれるので、それだとcatchには飛ばなくて少し悩みました。
なので
if($result['status'] !== 200) {
throw new \Exception('ステータスが正常ではありません');
}を書き足して、住所が取得できなかった場合もcatchに飛ぶように設定。
catch(\Exception $e) とは
コピペしたものを使っていて全く理解していなかった\Exceptionですが、
これはphpが用意しているExceptionクラスを指しています。
最初のバックスペース(\)はルートにあることを示すもの。「基本クラスを書く時はバックスラッシュから始める」というルールに基づいたものだそうです。
ただ、laravelの場合だとuseを使うことができるので、たとえば該当コントローラーの最初で
use Exception
とExceptionをuseする旨を書いておけば、コード内で\Exceptionと書く必要はなく、Exceptionのみの記述で大丈夫になります。
これはLaravelのモデルの扱いと同じですね!
ちなみに、Guzzleが用意しているTransferExceptionもこのphpのExceptionを継承しているので、Exceptionが最も大きく広い範囲で全てのエラー関連を拾うクラス、ということになります。
なので catch(\Exception $e) と書いておけば catch(\GuzzleHttp\Exception\TransferException $e) の方を使う必要は特にありません。
throw $e;
最後、catchのところでエラーの場合の処理を記述してゆきます。
今回は特にエラー対応の必要がなかったので書きませんでしたら、重要なエラーの場合など、「エラーがあったことを伝える」必要があるケースもあります。
その場合、
} catch(\Exception $e) {
throw $e;
}のように書いてエラーをスローします。
すると、tryの中で投げたスローはcatchへ行きますが、catchの中で投げたスローが呼び出し元(今回の場合コントローラーを呼び出している箇所)へ飛ぶことになります。


