Guzzleを使ってapiで郵便番号から住所検索/Laravel

Laravel

郵便番号から住所を取得するapiでcurlを使っていたところ

もっと今どきでかつセキュリティも高い書き方があると知り、早速そっちを使うことに。

laravel5.8で使用しました。

PHPでApi通信をするためのプラグイン「Guzzle」

Apiだけでもなかなか理解が追いついていないのですが、こういったプラグインを使うことでApi通信をより安全に行うことができるようです。

composer requireをして、(今回は)controller側で呼び出し&Api処理を記述してゆく形になります。

compose require周りの記述はこちらのサイト様をご覧ください。

【郵便番号APIを叩いてみた】PHPでGuzzleを使った(Api通信)
PHPでComposerからダウンロードしてGuzzleを使いました。 使い方とサンプルソースとデモページを乗せています。ぜひ参考にしてみてください。 Webシステム開発はCodelikeにお任せください

Guzzle自体のマニュアルはこちら

本番で弾かれる場合はリンクを修正

ローカルで試したところちゃんと動いたのですが、調べてみると本番で動かないことがあるとか。。

その場合は呼び出す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クラスを指しています。

最初のバックスペース(\)はルートにあることを示すもの。「基本クラスを書く時はバックスラッシュから始める」というルールに基づいたものだそうです。

このルートというのはphpのルート、という意味です。作業ディレクトリのことではありません。

ただ、laravelの場合だとuseを使うことができるので、たとえば該当コントローラーの最初で

use Exception

とExceptionをuseする旨を書いておけば、コード内で\Exceptionと書く必要はなく、Exceptionのみの記述で大丈夫になります。

これはLaravelのモデルの扱いと同じですね!

use を記述するときは、先頭のバックスラッシュは不要となります

ちなみに、Guzzleが用意しているTransferExceptionもこのphpのExceptionを継承しているので、Exceptionが最も大きく広い範囲で全てのエラー関連を拾うクラス、ということになります。

なので catch(\Exception $e) と書いておけば catch(\GuzzleHttp\Exception\TransferException $e) の方を使う必要は特にありません。

throw $e;

最後、catchのところでエラーの場合の処理を記述してゆきます。

今回は特にエラー対応の必要がなかったので書きませんでしたら、重要なエラーの場合など、「エラーがあったことを伝える」必要があるケースもあります。

その場合、

} catch(\Exception $e) { 
throw $e; 
}

のように書いてエラーをスローします。

すると、tryの中で投げたスローはcatchへ行きますが、catchの中で投げたスローが呼び出し元(今回の場合コントローラーを呼び出している箇所)へ飛ぶことになります。

タイトルとURLをコピーしました