erimeilis/laravel-cloudflare-d1
最新稳定版本:1.1.0
Composer 安装命令:
composer require erimeilis/laravel-cloudflare-d1
包简介
Production-ready Cloudflare D1 database driver for Laravel with full Eloquent support, 20x faster bulk inserts, and complete MySQL migration tooling
关键字:
README 文档
README
Supercharge your Laravel apps with Cloudflare's edge database
🌍 Deploy your database to Cloudflare's global edge network ⚡ 20x faster bulk inserts with automatic raw SQL optimization 🔄 One-command MySQL to D1 migration 🎯 Zero-config Eloquent ORM support — just works™
✨ Features
🎯 Core Functionality
- ✅ Drop-in Replacement — Works with existing Laravel database code
- 🔄 Full Eloquent ORM — Models, relationships, migrations, seeds... everything!
- 🛡️ Foreign Key Constraints — Automatically enabled (unlike standard SQLite)
- 📋 Schema Builder Support — Create/modify tables with familiar Laravel syntax
⚡ Performance & Optimization
- 🚀 20x Faster Bulk Inserts — Automatic raw SQL conversion (47s → 2.3s on 250 rows)
- 📦 Smart Chunking — Leverages D1's 100KB SQL limit vs 100-parameter limit
- 🔄 Zero Configuration — Works transparently with
insert(),insertOrIgnore(),upsert() - 🎯 Zero Overhead — Direct REST API communication with D1
- ⏱️ Production Tested — Validated with real-world workloads
🌍 Global Distribution
- 🌐 Edge Database — Data stored on Cloudflare's global network
- 🗺️ Low Latency — 50-150ms reads from anywhere in the world
- 📈 Scales to Zero — Pay only for what you use
- 💰 Free Tier Friendly — 500MB storage, 5M reads/day included
🔄 MySQL Migration
- 📦 One-Command Migration — Migrate entire MySQL database with single command
- 🎯 Smart Schema Conversion — Automatic MySQL→SQLite type mapping
- ✅ Data Integrity — Automatic validation and verification
- 🚀 High Performance — 33x faster with intelligent batching
🔧 Developer Experience
- 🎯 Laravel 11 & 12 Compatible — Tested with modern Laravel versions
- 🧪 Full Test Coverage — 57 automated tests, 100% passing
- 📖 Comprehensive Docs — Every feature explained with examples
- 💡 Easy Setup — 5-minute configuration, no complex setup
📦 Installation
composer require erimeilis/laravel-cloudflare-d1
The package will automatically register via Laravel's package discovery.
Requirements:
- PHP 8.2 or higher
- Laravel 11.x or 12.x
- Cloudflare account (free tier works!)
Getting Started with Cloudflare D1
Before using this package, you need to set up a D1 database in your Cloudflare account and get your credentials.
Step 1: Create a Cloudflare D1 Database
-
Sign up/Login to Cloudflare
- Go to dash.cloudflare.com
- Sign up for a free account or log in
-
Create a D1 Database
- In the Cloudflare dashboard, navigate to Workers & Pages → D1 SQL Database
- Click "Create database"
- Enter a database name (e.g.,
my-laravel-db) - Click "Create"
-
Note Your Database ID
- After creation, you'll see your database listed
- Click on your database name
- Copy the Database ID (looks like:
a1b2c3d4-e5f6-7890-abcd-ef1234567890)
Step 2: Get Your Cloudflare Credentials
🆔 Account ID
You can find your Account ID using any of these methods:
Method 1: From the URL (Easiest) ⚡
- Go to your Cloudflare dashboard: dash.cloudflare.com
- Look at the URL in your browser's address bar
- The Account ID is the string of characters immediately after
dash.cloudflare.com/- Example:
dash.cloudflare.com/1234567890abcdef1234567890abcdef/workers-and-pages - Your Account ID:
1234567890abcdef1234567890abcdef
- Example:
Method 2: Workers & Pages Section
- Go to dash.cloudflare.com
- Navigate to Workers & Pages in the left sidebar
- Look for the Account details section on the right
- Click Click to copy next to your Account ID
Method 3: Account Overview API Section
- Go to your Account Home in the dashboard
- Scroll down to the API section at the bottom of the page
- You'll see your Account ID displayed there
🔑 API Token
- Go to dash.cloudflare.com/profile/api-tokens
- Click "Create Token"
- Use the "Edit Cloudflare Workers" template OR create a custom token with these permissions:
- Account → D1 → Edit
- Click "Continue to summary"
- Click "Create Token"
- ⚠️ IMPORTANT: Copy your token immediately - you won't see it again!
📋 Quick Summary
You need three values:
- 🆔 CLOUDFLARE_ACCOUNT_ID: From dashboard URL or Workers & Pages section (see Method 1 above)
- 💾 CLOUDFLARE_D1_DATABASE_ID: From D1 database details page
- 🔑 CLOUDFLARE_D1_API_TOKEN: Generated via API Tokens page
⚙️ Configuration
1. Environment Variables
Add these to your .env file:
# Get from: Dashboard sidebar CLOUDFLARE_ACCOUNT_ID=1234567890abcdef1234567890abcdef # Get from: D1 database details page CLOUDFLARE_D1_DATABASE_ID=a1b2c3d4-e5f6-7890-abcd-ef1234567890 # Get from: API Tokens page (create new token) CLOUDFLARE_D1_API_TOKEN=your_secret_token_here
2. Database Configuration
Add to config/database.php:
'connections' => [ // ... existing connections 'd1' => [ 'driver' => 'd1', 'account_id' => env('CLOUDFLARE_ACCOUNT_ID'), 'database_id' => env('CLOUDFLARE_D1_DATABASE_ID'), 'api_token' => env('CLOUDFLARE_D1_API_TOKEN'), 'prefix' => '', 'prefix_indexes' => true, ], ],
3. Publish Configuration (Optional)
php artisan vendor:publish --provider="EriMeilis\CloudflareD1\D1ServiceProvider" --tag="config"
This creates config/cloudflare-d1.php for advanced configuration.
🧪 Quick Start Testing
Want to verify everything works? Here's a 2-minute test:
Test 1: Check Connection
php artisan tinker
// Test the connection DB::connection('d1')->select('SELECT 1 as test'); // Should return: [{"test": 1}]
Test 2: Create a Table
Create a simple migration:
php artisan make:migration create_test_users_table
Edit the migration:
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { protected $connection = 'd1'; public function up(): void { Schema::connection('d1')->create('test_users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamps(); }); } public function down(): void { Schema::connection('d1')->dropIfExists('test_users'); } };
Run the migration:
php artisan migrate --database=d1
Test 3: Insert and Query Data
php artisan tinker
// Insert DB::connection('d1')->table('test_users')->insert([ 'name' => 'Alice', 'email' => 'alice@example.com', 'created_at' => now(), 'updated_at' => now(), ]); // Query $users = DB::connection('d1')->table('test_users')->get(); // Should return your inserted record! // Test batching (10x faster!) DB::connection('d1')->transaction(function () { for ($i = 1; $i <= 10; $i++) { DB::connection('d1')->table('test_users')->insert([ 'name' => "User {$i}", 'email' => "user{$i}@example.com", 'created_at' => now(), 'updated_at' => now(), ]); } }); // All 10 INSERTs executed in ONE batch API call! 🚀
Test 4: Eloquent Model
Create a model:
php artisan make:model TestUser
namespace App\Models; use Illuminate\Database\Eloquent\Model; class TestUser extends Model { protected $connection = 'd1'; protected $table = 'test_users'; protected $fillable = ['name', 'email']; }
Use it:
php artisan tinker
// Create $user = App\Models\TestUser::create([ 'name' => 'Bob', 'email' => 'bob@example.com' ]); // Find $user = App\Models\TestUser::find(1); // Update $user->update(['name' => 'Bob Updated']); // All $users = App\Models\TestUser::all();
✅ If all tests pass, you're ready to use D1 in your Laravel app!
📚 Usage
🎯 Models
Use D1 exactly like any other Laravel database:
namespace App\Models; use Illuminate\Database\Eloquent\Model; class User extends Model { protected $connection = 'd1'; protected $fillable = ['name', 'email']; } // Usage User::create(['name' => 'Alice', 'email' => 'alice@example.com']); $users = User::where('active', true)->get();
🏗️ Migrations
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { protected $connection = 'd1'; public function up(): void { Schema::connection('d1')->create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamps(); }); } public function down(): void { Schema::connection('d1')->dropIfExists('users'); } };
Run migrations:
php artisan migrate --database=d1
🔧 Query Builder
use Illuminate\Support\Facades\DB; // Select $users = DB::connection('d1') ->table('users') ->where('active', true) ->get(); // Insert DB::connection('d1') ->table('users') ->insert([ 'name' => 'Bob', 'email' => 'bob@example.com', ]); // Update DB::connection('d1') ->table('users') ->where('id', 1) ->update(['name' => 'Bob Updated']); // Delete DB::connection('d1') ->table('users') ->where('id', 1) ->delete();
⚡ Performance Optimization
1. 🚀 Use Transactions for Bulk Operations (10x Faster!)
DB::connection('d1')->transaction(function () { foreach ($users as $userData) { User::create($userData); } }); // All INSERTs executed in a single batch API call!
Performance: 10 INSERTs go from ~1000ms to ~150ms
2. 🔗 Eager Load Relationships
// ❌ Bad: N+1 queries $users = User::all(); foreach ($users as $user) { echo $user->posts->count(); } // ✅ Good: 2 queries total $users = User::with('posts')->get();
3. 📦 Chunk Large Datasets
User::chunk(1000, function ($users) { foreach ($users as $user) { // Process } });
🔧 Advanced Configuration
💾 Multiple D1 Databases
// config/database.php 'connections' => [ 'd1_primary' => [ 'driver' => 'd1', 'database_id' => env('D1_PRIMARY_DATABASE_ID'), // ... ], 'd1_analytics' => [ 'driver' => 'd1', 'database_id' => env('D1_ANALYTICS_DATABASE_ID'), // ... ], ],
📊 Custom Batch Size
// config/cloudflare-d1.php 'batch' => [ 'enabled' => true, 'size' => 100, // Max queries per batch (1-100) ],
⚡ Query Caching (Read-Heavy Workloads)
// config/cloudflare-d1.php 'cache' => [ 'enabled' => true, 'driver' => 'redis', 'ttl' => 300, // 5 minutes ],
🔍 How It Works
- 🔌 Custom PDO Driver: Translates PDO calls to D1 REST API requests
- 📦 Query Batching: Accumulates queries in transactions → single batch API call
- 📝 SQLite Grammar: D1 uses SQLite syntax, so we extend Laravel's SQLite grammar
- 🔗 Foreign Keys: Automatically enabled (disabled by default in SQLite)
🏗️ Architecture
Laravel Eloquent/Query Builder
↓
D1 Connection
↓
D1 PDO
↓
Query Batcher (batching enabled in transactions)
↓
D1 API Client
↓
Cloudflare D1 REST API
⚠️ Limitations
🔧 D1/SQLite Limitations
- ❌ No FULLTEXT indexes → Use Laravel Scout for full-text search
- ❌ No stored procedures → Move logic to application layer
- ⚠️ Limited ALTER TABLE → Some schema changes require table rebuild
- ✅ 100 parameter limit per query → Automatically handled by this package
- 💾 Database size: 10 GB max (Paid plan), 500 MB (Free plan)
📊 Performance Characteristics
- 🎯 Best for: Read-heavy workloads, globally distributed apps
- ⏱️ Write latency: ~50-200ms per query (50-150ms with batching)
- 🚀 Read latency: ~50-150ms per query
- ⚡ Batch operations: 10-11x faster for multiple operations
🛠️ Troubleshooting
🔗 Foreign Key Constraint Errors
D1/SQLite has foreign keys disabled by default. This package automatically enables them, but if you encounter issues:
// Manually enable DB::connection('d1')->statement('PRAGMA foreign_keys = ON'); // Or disable for specific operations DB::connection('d1')->disableForeignKeyConstraints(); // ... operations ... DB::connection('d1')->enableForeignKeyConstraints();
⚡ Slow Query Performance
Enable query logging to identify slow queries:
// config/cloudflare-d1.php 'monitoring' => [ 'slow_query_threshold' => 1000, // Log queries > 1000ms 'log_api_requests' => true, ],
🔐 API Authentication Errors
Error: "D1 API request failed: Unauthorized" or "Invalid credentials"
This means your Cloudflare credentials are incorrect or missing. Verify them:
# Check environment variables are loaded php artisan tinker >>> env('CLOUDFLARE_ACCOUNT_ID') >>> env('CLOUDFLARE_D1_DATABASE_ID') >>> env('CLOUDFLARE_D1_API_TOKEN')
If any return null, check:
-
Environment file: Ensure
.envhas the correct values (no quotes needed) -
Config cache: Clear Laravel's config cache
php artisan config:clear
-
Credential format:
- Account ID: 32-character hexadecimal (e.g.,
1234567890abcdef1234567890abcdef) - Database ID: UUID format (e.g.,
a1b2c3d4-e5f6-7890-abcd-ef1234567890) - API Token: Long alphanumeric string starting with token identifier
- Account ID: 32-character hexadecimal (e.g.,
-
API Token permissions: Ensure your token has D1 Edit permissions
- Go to API Tokens
- Click on your token
- Verify it has "Account - D1 - Edit" permission
Error: "Database not found" or "Database ID invalid"
-
Verify the database ID is correct:
- Go to Cloudflare D1 Dashboard
- Navigate to Workers & Pages → D1 SQL Database
- Click on your database
- Copy the Database ID from the details page
-
Ensure the database exists and is associated with the correct account
Common Mistakes:
- ❌ Using quotes around values in
.env:CLOUDFLARE_ACCOUNT_ID="abc123"(wrong) - ✅ No quotes:
CLOUDFLARE_ACCOUNT_ID=abc123(correct) - ❌ Missing
.enventry after adding toconfig/database.php - ❌ Using old cached config after changing
.env(runphp artisan config:clear) - ❌ API token without sufficient permissions
🔄 MySQL to D1 Migration
Migrate your existing MySQL database to Cloudflare D1 with one command!
Quick Migration
# Migrate all tables php artisan d1:migrate-from-mysql # Preview first (dry run) php artisan d1:migrate-from-mysql --dry-run # Migrate specific tables only php artisan d1:migrate-from-mysql --tables=users,posts,comments # Exclude specific tables php artisan d1:migrate-from-mysql --exclude=logs,cache
What Gets Migrated
✅ Schema Conversion
- All MySQL data types → SQLite equivalents
- AUTO_INCREMENT → AUTOINCREMENT
- ENUM → TEXT with CHECK constraints
- Foreign keys with CASCADE actions
- Indexes (regular and UNIQUE)
✅ Data Migration
- Memory-efficient chunked export
- Batch INSERT operations (33x faster)
- Progress tracking
- Automatic validation
Migration Features
- One-Command Migration: Complete database migration in a single Artisan command
- Selective Migration: Choose which tables to migrate with
--tablesor--exclude - Structure Only: Migrate schema without data using
--structure-only - Data Only: Migrate data into existing tables using
--data-only - Dry Run: Preview migration plan without executing
- Validation: Automatic row count and data integrity verification
Complete Migration Guide
For detailed migration instructions, schema conversion details, troubleshooting, and best practices, see MIGRATION_GUIDE.md.
🧪 Testing
composer test
🤝 Contributing
Contributions are welcome! Please:
- 🍴 Fork the repository
- 🌿 Create a feature branch
- ✅ Add tests for new functionality
- 🚀 Submit a pull request
📄 License
MIT License - see LICENSE file
Made with 💙💛 using Laravel and Cloudflare D1
统计信息
- 总下载量: 60
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 2
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-11-03