郵便番号から住所を取得する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の中で投げたスローが呼び出し元(今回の場合コントローラーを呼び出している箇所)へ飛ぶことになります。