【Laravel】全国の駅データをさくっと取得【PHP】

APIを使用して、全国の駅データを取得してDBに入れてみる

使用するAPI

上記で提供されている
http://express.heartrails.com/api/json
にリクエストを投げて取得する

テーブル作成

  • 沿線テーブルと駅テーブルを作成する
php artisan make:migration create_lines_table
php artisan make:migration create_stations_table
  • CreateLinesTable
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateLinesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('lines', function (Blueprint $table) {
            $table->bigIncrements('id');
            // 都道府県IDはconfigファイルで設定するかprefecturesテーブルを作る。ここでは割愛
            $table->tinyInteger('prefecture_id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('lines');
    }
}

都道府県IDをconfigで管理する場合は以下記事参照

  • CreateStationsTable
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateStationsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('stations', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('line_id');
            $table->foreign('line_id')->references('id')->on('lines');
            $table->string('name');
            $table->decimal('lon', $precision = 9, $scale = 6)->nullable();
            $table->decimal('lat', $precision = 9, $scale = 6)->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('stations');
    }
}

駅情報を取得するコマンド作成

  • app/Console/Commands/FetchStation.php
  1. 都道府県一覧取得
  2. 都道府県一覧をループして紐づく沿線一覧を取得
  3. 沿線一覧をループして紐づく駅一覧を取得
<?php

namespace App\Console\Commands;

use App\Models\Line;
use App\Models\Station;
use Illuminate\Console\Command;

/**
 * 駅データ取得
 */
class FetchStation extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'fetch:station';
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '駅データ取得';

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        try {
            $base_url = 'http://express.heartrails.com/api/json';
            /**
             * 都道府県情報を取得
             */
            $url = "{$base_url}?method=getPrefectures";
            $response = file_get_contents($url);
            $data = json_decode($response, true);
            foreach ($data['response']['prefecture'] as $prefecture_index => $prefecture_name) {
                /**
                 * 沿線情報を取得
                 */
                $url = "{$base_url}?method=getLines&prefecture={$prefecture_name}";
                $response = file_get_contents($url);
                $data = json_decode($response, true);
                foreach ($data['response']['line'] as $line_name) {
                    // 沿線データがテーブルになければ登録
                    $line = Line::query()->firstOrCreate([
                           'name' => $line_name
                        ], [
                            'prefecture_id' => $prefecture_index + 1,
                            'name' => $line_name
                        ]);

                    /**
                     * 駅情報を取得
                     */
                    $url = "{$base_url}?method=getStations&line={$line_name}";
                    $response = file_get_contents($url);
                    $data = json_decode($response, true);
                    foreach ($data['response']['station'] as $station) {
                        // 駅データがテーブルになければ登録
                        Station::query()->firstOrCreate([
                            'name' => $station['name']
                            ], [
                                'line_id' => $line->id,
                                'name' => $station['name'],
                                'lon' => $station['x'],
                                'lat' => $station['y'],
                            ]);
                    }
                }
            }
        } catch (\Exception $e) {
            echo $e->getMessage();
        }
    }
}

  • コマンド実行
php artisan fetch:station
  • getPrefecturesのレスポンスの中身
array:1 [
  "response" => array:1 [
    "prefecture" => array:47 [
      0 => "北海道"
      1 => "青森県"
      2 => "岩手県"
      3 => "宮城県"
      4 => "秋田県"
      5 => "山形県"
      6 => "福島県"
      7 => "茨城県"
      8 => "栃木県"
      9 => "群馬県"
      10 => "埼玉県"
// 省略
  • getLinesのレスポンスの中身
array:1 [
  "response" => array:1 [
    "line" => array:24 [
      0 => "JR函館支線"
      1 => "JR函館本線"
      2 => "JR千歳線"
      3 => "JR宗谷本線"
      4 => "JR室蘭支線"
      5 => "JR室蘭本線"
      6 => "JR富良野線"
      7 => "JR日高本線"
// 省略

  • getStationsのレスポンスの中身
array:1 [
  "response" => array:1 [
    "station" => array:8 [
      0 => array:8 [
        "name" => "大沼"
        "prefecture" => "北海道"
        "line" => "JR函館支線"
        "x" => 140.669347
        "y" => 41.971954
        "postal" => "0411354"
        "prev" => null
        "next" => "鹿部"
      ]
      1 => array:8 [
        "name" => "鹿部"
        "prefecture" => "北海道"
// 省略

取得後

  • 沿線

\ 案件のご依頼・ご相談はこちらから /