erimeilis/laravel-cloudflare-d1
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 & 13 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, 12.x, or 13.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
erimeilis/laravel-cloudflare-d1 适用场景与选型建议
erimeilis/laravel-cloudflare-d1 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 638 次下载、GitHub Stars 达 8, 最近一次更新时间为 2025 年 11 月 03 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「database」 「performance」 「sqlite」 「laravel」 「cloudflare」 「eloquent」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 erimeilis/laravel-cloudflare-d1 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 erimeilis/laravel-cloudflare-d1 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 erimeilis/laravel-cloudflare-d1 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Dibi is Database Abstraction Library for PHP
g4 application profiler package
CSS/Javascript Minificator, Compressor and Concatenator for TYPO3 - highly configurable frontend asset optimization for CSS/JS merging, minification and compression with optional body parsing, async/defer loading, inline output, data-ignore exclusions, SRI integrity validation/calculation, external
WordPress mu-plugin to remove jQuery Migrate from the list of jQuery dependencies and to allow jQuery to enqueue before </body> instead of in the <head>.
Store your language lines in the database, yaml or other sources
The tenancy/tenancy database driver for sqlite
统计信息
- 总下载量: 638
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 8
- 点击次数: 30
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-11-03