Try   HackMD

laravel排程下載外部Url檔案,及更新進資料庫資料

如何下載外部公開URL

首先利用Client套件下載外部url的csv檔案。

本文撰寫使用抓取此網址https://od.cdc.gov.tw/acute/幼兒常規疫苗接種時間試算表.csv為範例

public function download() { $client = new \GuzzleHttp\Client(); $a = $client->get('https:/example/example.csv', ['save_to' => resource_path() . '/download/file.csv']); return response(200); }

如何將下載檔案匯進資料庫

使用laravel-excel套件將下載的檔案import進資料庫

laravel-excel安裝

因為等等會用到先說說laravel ORM的firstOrCreate方法

功能 : 將嘗試使用給定的列/值對定位數據庫記錄。如果在數據庫中找不到模型,則會插入一條記錄,其中包含將第一個數組參數與可選的第二個數組參數合併後的屬性

以下為文檔範例:

use App\Models\Flight; // Retrieve flight by name or create it if it doesn't exist... $flight = Flight::firstOrCreate([ 'name' => 'London to Paris' ]); // Retrieve flight by name or create it with the name, delayed, and arrival_time attributes... $flight = Flight::firstOrCreate( ['name' => 'London to Paris'], ['delayed' => 1, 'arrival_time' => '11:30'] );

再來先創建要傳遞的類
檔案可以放在 app/imports/ExampleImport.php

<?php namespace App\Imports; use App\Vaccination; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\ToCollection; class VaccinationImport implements ToCollection { public function collection(Collection $rows) { foreach ($rows as $k => $row) { if ($k < 1) continue; // 跳過標題 Vaccination::firstOrCreate([ // 'age' => $row[0], 'kind' => $row[1], 'remark' => $row[3] ]); } } }

將 VaccinationImport 對像傳遞給Excel::import()方法,將告訴包如何導入作為第二個參數傳遞的文件,第二個參數的文件就是上面程式碼下載下來的csv檔案放置位置。

該文件應該位於您的默認文件系統磁盤中(參考資料config/filesystems.php)。

public function import() { // 我沒有讓它找默認的,讓他尋找resource資料夾底下檔案 Excel::import(new VaccinationImport, resource_path('/download/file.csv')); }

功能合併新增排程

在cmd輸入以下指令,創建command檔案,算是一個可以自己寫命令(shell)的檔案

php artisan make:command DownloadCSV

接著在DownloadCSV.php中修改

<?php namespace App\Console\Commands; use Illuminate\Console\Command; use App\Imports\VaccinationImport; use Maatwebsite\Excel\Facades\Excel; class DownloadCSV extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'download:vaccination'; // 定義一個命令 /** * The console command description. * * @var string */ protected $description = '排程自動下載資料,對比資料庫寫入'; // 一些介紹 /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return int */ public function handle() // 主要程式碼 { $this->download(); // 下載外部csv $this->import(); // 對比資料庫更新及新增 } public function download() { $client = new \GuzzleHttp\Client(); $client->get('https:/example/example.csv', ['save_to' => resource_path() . '/download/file.csv']); return response(200); } public function import() { Excel::import(new VaccinationImport, resource_path('/download/file.csv')); } }

修改完成接下來到app/Console/Kernel.php

修改及導入命令程式碼

<?php namespace App\Console; use App\Console\Commands\DownloadCSV; // 導入 use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel { /** * The Artisan commands provided by your application. * * @var array */ protected $commands = [ DownloadCSV::class ]; /** * Define the application's command schedule. * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void */ // 定義要排程的指令或流程 protected function schedule(Schedule $schedule) { // 這邊就會跑command檔案handle函式 // 設定為一個小時跑一次 $schedule->command('download:vaccination')->hourly(); } /** * Register the commands for the application. * * @return void */ protected function commands() { $this->load(__DIR__.'/Commands'); require base_path('routes/console.php'); } }

程式碼部分就算完成了,接下來就是要設定排程工作

我是在Linux上面做開發,如要要讓它排程就要加入 CronJob

在Linux上輸入

crontab -e

按i編輯,輸入以下這行,它是告訴這個package每一分鐘run一次php artisan schedule:run 就是跑排程的意思。

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

path-to-your-project改成你的專案路徑

輸入完畢按下esc,然後輸入:wq離開並儲存,跑出以下這行表示成功拉

crontab: installing new crontab

參考資料

更多相關排程時間參考這裡

更多排程相關資料請參照laravel Task Scheduling 文檔