如何在Laravel中每12小时执行Restful API调用并更新数据库?
Got it, let's break down exactly how to implement this scheduled API sync in Laravel—this is a common use case, so we'll leverage Laravel's built-in task scheduler and a custom Artisan command to handle the workflow smoothly.
1. Create a Custom Artisan Command
First, we need a dedicated command to handle API calls, data cleanup, and storage. Run this in your project root:
php artisan make:command FetchAndStoreApiData
This generates a new file at app/Console/Commands/FetchAndStoreApiData.php. Open it and build out the core logic:
Configure Command Metadata
Set a clear signature and description for the command:
protected $signature = 'fetch:api-data'; protected $description = 'Pull data from REST API, clear existing records, and save new data to database';
Implement the Core Workflow (handle() Method)
In the handle() method, we'll execute three key actions: call the API, wipe old data, and insert new records. We'll use Laravel's Http client for API calls and assume you already have a model (e.g., App\Models\ApiData) mapped to your target database table.
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; use App\Models\ApiData; public function handle() { try { // 1. Call the REST API $response = Http::get('https://your-api-endpoint.com/your-data-path'); // Validate API response if (!$response->successful()) { Log::error('API request failed with status code: ' . $response->status()); return $this->error('API request failed'); } $rawApiData = $response->json(); // 2. Clear existing database records // Use truncate() for fast full-table cleanup (resets auto-increment IDs) ApiData::truncate(); // If you need to delete specific records instead, use: // ApiData::where('some_condition', true)->delete(); // 3. Format and insert new data // Map API fields to your database columns (adjust this to match your schema) $formattedRecords = collect($rawApiData)->map(function ($item) { return [ 'title' => $item['api_title'], 'value' => $item['api_value'], 'created_at' => now(), 'updated_at' => now(), ]; })->toArray(); // Batch insert for better performance (vs. individual create() calls) ApiData::insert($formattedRecords); $this->info("Successfully synced " . count($formattedRecords) . " records"); Log::info("API data sync completed: " . count($formattedRecords) . " records added"); } catch (\Exception $e) { Log::error('API sync failed: ' . $e->getMessage(), ['trace' => $e->getTraceAsString()]); $this->error('Sync failed: ' . $e->getMessage()); } }
2. Set Up Task Scheduling
Next, we'll configure Laravel to run this command every 12 hours. Open app/Console/Kernel.php and update the schedule() method:
protected function schedule(Schedule $schedule) { // Run our custom command every 12 hours $schedule->command('fetch:api-data')->everyTwelveHours(); // Optional: If you want to run at specific times (e.g., 00:00 and 12:00 daily) // $schedule->command('fetch:api-data')->dailyAt('00:00')->dailyAt('12:00'); }
3. Configure Server Cron Job
Laravel's scheduler relies on the system's Cron service to trigger it every minute. You need to set up a Cron job on your server:
- Log into your server and run
crontab -eto edit the Cron list. - Add this line (replace
/path-to-your-projectwith the absolute path to your Laravel root directory):
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
This tells Cron to run Laravel's scheduler every minute—Laravel will then check if your 12-hour task is due to execute.
Testing & Debugging
- Test the command directly: Run
php artisan fetch:api-datamanually to verify it clears old data, fetches new data, and inserts it correctly. Checkstorage/logs/laravel.logfor any errors. - Test the scheduler: Temporarily change the schedule to
->everyMinute()to verify the task triggers automatically, then switch back toeveryTwelveHours()once confirmed.
Extra Tips for Production
- API Authentication: If your API requires a token, add it to the request:
Http::withToken('your-api-token')->get('...') - Data Validation: Add validation rules before inserting data to avoid invalid records (use Laravel's
Validatorclass). - Timeout Handling: Set a timeout for slow API requests:
Http::timeout(30)->get('...') - Queue Large Imports: If the API returns massive datasets, offload the insertion to a queue job to avoid long-running tasks.
内容的提问来源于stack exchange,提问作者Shola Michael

