鶏口牛後な日々

心の赴くまま、やりたいことを仕事に。

AjaxとMySQLとPHP Laravelで郵便番号から住所検索するボタンを実装する

全体像

めちゃめちゃ大まかには、HTML→データベース→PHP Laravel→JS の順で、それぞれ用意していく必要があります。 もう少しブレイクダウンします。↓

  1. HTMLにフォームを用意し、郵便番号入力欄と住所入力欄と検索ボタンを作る

  2. MySQLに、郵便番号と住所のテーブルを用意する

  3. PHP Laravelで、郵便番号テーブルのモデルを作る

  4. PHP Laravelで、郵便番号を操作するコントローラーを作り、郵便番号テーブルから郵便番号に一致する住所を取得するメソッドを追加する *PHP Laravelで、ルートの設定を行う

  5. jsファイルに、ajaxで上記のメソッドを呼び出し、HTMLの郵便番号入力欄に入力された番号をデータとして渡すよう定義する

  6. ajaxメソッド内にて通信の成功が確認

  7. 成功した場合に、取得した住所をHTMLの住所入力欄に記載するようjsを追加する

一つずつ解説します。

1. HTMLでフォーム準備

<div class="form-group">
    <label for="postal_code">郵便番号</label>
    <input type="text" id="postal_code" name="postal_code">
</div>
<button type="button" id="get_address">住所検索</button>

<div class="form-group">
    <label for="address">住所</label>
    <input type="text" id="address" name="address">
</div>

作るものは3つ。

郵便番号の入力欄と、住所検索ボタンと、住所入力欄です。

このとき、注意点としては、ボタンタグには type="button" をつけるのを忘れないようにしてください。

私はこれを忘れてハマりました。

ボタンタグは、type属性をつけないと、defaultで type="submit"になってしまうので、なぜか画面が遷移してしまい、PHPかJSのエラーと勘違いしてえらく調べても何もわからず苦戦しました。

つける手間は大したことがないですが、つけずにハマると、原因がわかるまで結構苦戦することがありますので、つけるのを習慣としようとその時思いました。ご参考まで。

2. MySQLでテーブル準備

MySQLでテーブルを作ります。

Laravelだとmigrationファイルですね。

項目は、郵便番号とそれに該当する住所があれば他は特に何も必要ありません。

実際のデータは、郵便局が公開しているCSVがあるのでこちらをダウンロードしてインポートします。

仮にこちらのテーブルは、 postalcodes テーブルとします。

3. PHP Laravelでモデル準備

PHP Laravelで、上記で作ったテーブルのコンテンツを操作できるModelを作ります。

php artisan make:model モデル名 だけで中身は空のModelファイルができます。

今回は難しい操作はしないので、これだけでOK.

テーブル名が、 postalcodes なので、Model名は規約に則り Postalcode モデルとします。

カラム名として、郵便番号を入れるカラムを postal_code 、住所を入れるカラムを address としておきます。

4. PHP Laravelでコントローラーのメソッド準備

PHP Laravelで郵便番号関連の操作をするコントローラを作ります。

php aritisan make:controller AddressController とかでOK.

ここには、郵便番号を受け取って、住所を返すメソッドを一つ追加します。

コントローラーのファイルの上部で、さっき作った Postalcodeモデルを use しておくのを忘れないようにしてください。

    public function getAddressByPostalCode($postalCode)
    {
        $addresses = Postalcode::where('postal_code', $postalCode)->groupBy('address')->pluck('address');

        return response()->json($addresses);
    }

$postalCodeを引数に取っています。 Postalcodeモデルを使って、引数として取ってきた郵便番号にマッチする住所を取得しています。

リターンするのは、ajaxなので、json形式で返します。

5. PHP Laravelでルートの設定を行う

ルートファイルに、ajaxから呼び出すためのURLを定義します。

以下のような形です。

Route::get('/postal-code/{postal-code}/address', 'AddressController@getAddressByPostalCode'); 

6. JavaScriptajaxのメソッド準備

ajaxは、JavaScriptの書き方でももちろんいいのですが、jQuery$.ajax というメソッドが簡単に書けるので今回はそれで書きました。

    /* Ajax通信開始 */
    $('#get_address').on('click', function(){
        var postal_code = $('#postal_code').val();
        var request = $.ajax({
            type: 'GET',
            url: '/postal-code/' + postal_code + '/address',
            cache: false,
            dataType: 'json',
            timeout: 3000
        });

    /* 成功時 */
        request.done(function(data){
            alert("通信に成功しました");
        });

    /* 失敗時 */
        request.fail(function(){
            alert("通信に失敗しました");
        });

    });

まず #get_address というidのボタンをクリックしたら、通信を開始します。

postal_code という変数を定義し、そこに、IDが postal_code となっているインプットに入力されている内容を入れています。

type はgetかpostかを指定します。ここでは住所を取得するのみですので、getとします。

これは、先ほど定義したルートのパラメータとして、 url のなかで呼び出すURLに含めています。

dataTypejsonとしましたが、クロスドメインの場合は、 jsonpとするようです。その場合、コールバック関数を入れる必要もあるようですので、必要な人は別途調べてください。

timeout は、通信がエラーとなった時、何秒間でエラーと判断するかという秒数です。 3000 としているので、3秒間待ってダメならばエラーとするということになります。

7. ajax疎通確認

上記のように書いて、実際に動作させてみます。

もし、「通信に成功しました」というalertが出れば、通信成功です。

失敗した場合は、urlをダブルチェックしましょう。最初のスラッシュ / が抜けているなどはよくあることです。

また、ブラウザのネットワークタブなどで、通信が成功しているか? レスポンス 200 が帰ってきているかなどをチェックすると良いと思います。

一番多いのは、ルートの間違いや、urlの指定間違いだと思います。

8. ajaxで取得したデータをHTMLに記載する記述をJavaScriptに追記

alertで「通信に成功しました」が出たら、成功した時の記述を、 /* 成功時 */ に追記します。

今回は、取得した内容を住所のインプット欄に記載するだけなので、以下の1文を追記します。

$('#address').val(data[0]);

これでインプット欄にデータをペースとしてくれるはずです。

もしペーストがうまくいかない場合は、取得したデータが本当に中に入っているか? を確認してみましょう。

確認する方法としては、

alert("通信に成功しました") 付近に、 console.log(data[0]) などとしてみることです。

json形式で帰ってきているので、中のデータにアクセスする場合は、配列の中身をみるように、 data[0] とします。

以上です!