PHP & Laravel Integration
PHP & Laravel Integration
WeftKit Standalone speaks standard wire protocols, so every existing PHP database driver and Laravel integration works without modification. This guide covers PHP PDO, Composer libraries, and full Laravel integration for each WeftKit engine.
Prerequisites
- WeftKit Standalone running and reachable (see Deployment)
- PHP 8.2 or later
- Composer
php-pgsqlandphp-mongodbextensions installed
Composer Dependencies
bash# Core drivers composer require mongodb/mongodb # WeftKitDoc composer require predis/predis # WeftKitMem composer require laudis/neo4j-php-client # WeftKitGraph # Laravel-specific packages composer require mongodb/laravel-mongodb # WeftKitDoc in Laravel
1. WeftKitRel via PHP PDO
WeftKitRel speaks the PostgreSQL v3 wire protocol. PHP's built-in PDO connects to it using the pgsql driver.
Connecting
php<?php declare(strict_types=1); $dsn = 'pgsql:host=localhost;port=5432;dbname=mydb'; $user = 'app_user'; $pass = 'secret'; try { $pdo = new PDO($dsn, $user, $pass, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]); } catch (PDOException $e) { throw new RuntimeException('Cannot connect to WeftKitRel: ' . $e->getMessage()); }
Prepared Statements and Queries
php// Parameterised SELECT — safe against SQL injection $stmt = $pdo->prepare( 'SELECT id, name, email FROM users WHERE age > :min_age ORDER BY name' ); $stmt->execute(['min_age' => 18]); $users = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($users as $user) { echo $user['name'] . ' — ' . $user['email'] . PHP_EOL; }
INSERT with Returning
php$stmt = $pdo->prepare( 'INSERT INTO users (name, email, age) VALUES (:name, :email, :age) RETURNING id' ); $stmt->execute([ 'name' => 'Alice', 'email' => 'alice@example.com', 'age' => 30, ]); $id = (int) $stmt->fetchColumn(); echo "Created user with ID: {$id}";
Transactions
phptry { $pdo->beginTransaction(); $pdo->prepare('UPDATE accounts SET balance = balance - :amount WHERE id = :from_id') ->execute(['amount' => 100.00, 'from_id' => 1]); $pdo->prepare('UPDATE accounts SET balance = balance + :amount WHERE id = :to_id') ->execute(['amount' => 100.00, 'to_id' => 2]); $pdo->commit(); } catch (PDOException $e) { $pdo->rollBack(); throw $e; }
2. WeftKitDoc via mongodb/mongodb PHP Library
WeftKitDoc speaks the MongoDB Wire protocol. The official MongoDB PHP library connects to it directly.
Connecting
php<?php use MongoDB\Client; $client = new Client('mongodb://app_user:secret@localhost:27017'); $db = $client->selectDatabase('mydb'); $col = $db->selectCollection('articles');
Inserting Documents
php// Single insert $result = $col->insertOne([ 'title' => 'Getting Started with WeftKit', 'author' => 'Alice', 'tags' => ['database', 'weftkit'], 'views' => 0, 'created' => new MongoDB\BSON\UTCDateTime(), ]); echo "Inserted ID: " . $result->getInsertedId(); // Bulk insert $result = $col->insertMany([ ['title' => 'MVCC Deep Dive', 'author' => 'Bob', 'views' => 0], ['title' => 'Vector Search', 'author' => 'Carol', 'views' => 0], ]); echo "Inserted " . $result->getInsertedCount() . " documents";
Finding Documents
php// Find one $article = $col->findOne(['author' => 'Alice']); if ($article !== null) { echo $article['title']; } // Find many with filter and options $cursor = $col->find( ['tags' => 'database'], ['sort' => ['views' => -1], 'limit' => 10] ); foreach ($cursor as $doc) { echo $doc['title'] . ' — ' . $doc['views'] . ' views' . PHP_EOL; }
Updating Documents
php// Update one $col->updateOne( ['title' => 'Getting Started with WeftKit'], ['$set' => ['views' => 1500, 'featured' => true]] ); // Update many $col->updateMany( ['author' => 'Bob'], ['$inc' => ['views' => 10]] );
Aggregation Pipeline
php$cursor = $col->aggregate([ ['$match' => ['views' => ['$gt' => 100]]], ['$group' => [ '_id' => '$author', 'total_views' => ['$sum' => '$views'], 'count' => ['$sum' => 1], ]], ['$sort' => ['total_views' => -1]], ['$limit' => 5], ]); foreach ($cursor as $result) { echo $result['_id'] . ': ' . $result['total_views'] . ' total views' . PHP_EOL; }
3. WeftKitMem via predis/predis
WeftKitMem speaks Redis RESP3. Predis connects to it using the standard Redis protocol.
Connecting
php<?php use Predis\Client; $client = new Client([ 'scheme' => 'tcp', 'host' => 'localhost', 'port' => 6379, 'password' => 'secret', 'database' => 0, ]);
String Commands
php// Set with expiry (in seconds) $client->setex('session:abc123', 1800, 'user_42'); // Get $value = $client->get('session:abc123'); if ($value === null) { echo "Key not found or expired"; } else { echo "Session user: {$value}"; } // Atomic increment $views = $client->incr('article:42:views');
Hash Commands
php// Set multiple fields $client->hmset('user:42', [ 'name' => 'Alice', 'email' => 'alice@example.com', 'plan' => 'pro', ]); // Get all fields $user = $client->hgetall('user:42'); echo $user['name'] . ' — ' . $user['plan']; // Get one field $email = $client->hget('user:42', 'email');
List Commands
php// Push to list $client->lpush('tasks:queue', 'task_3', 'task_2', 'task_1'); // Non-blocking pop $task = $client->rpop('tasks:queue'); // Read range $all = $client->lrange('tasks:queue', 0, -1);
Pipeline
php$responses = $client->pipeline(function ($pipe) { $pipe->set('key:1', 'value_1'); $pipe->set('key:2', 'value_2'); $pipe->incr('pipeline:counter'); $pipe->expire('key:1', 600); }); // $responses is an array of return values, one per command
4. WeftKitGraph via Bolt PHP Client
WeftKitGraph speaks the Bolt protocol (same as Neo4j). Use the laudis/neo4j-php-client library.
Connecting
php<?php use Laudis\Neo4j\ClientBuilder; $client = ClientBuilder::create() ->withDriver('bolt', 'bolt://app_user:secret@localhost:7687') ->withDefaultDriver('bolt') ->build();
Running Cypher Queries
php// Write — create nodes and a relationship $client->writeTransaction(static function ($transaction) { $transaction->run( 'MERGE (a:Person {name: $name1}) MERGE (b:Person {name: $name2}) MERGE (a)-[:FRIEND]->(b)', ['name1' => 'Alice', 'name2' => 'Bob'] ); }); // Read — traverse the graph $result = $client->readTransaction(static function ($transaction) { return $transaction->run( 'MATCH (p:Person {name: $name})-[:FRIEND]->(f:Person) RETURN f.name AS name, f.age AS age', ['name' => 'Alice'] ); }); foreach ($result as $record) { echo $record->get('name') . ' (age ' . $record->get('age') . ')' . PHP_EOL; }
5. Laravel — WeftKitRel
config/database.php
Add a WeftKit connection block:
php'connections' => [ 'weftkit' => [ 'driver' => 'pgsql', 'host' => env('WEFTKIT_HOST', 'localhost'), 'port' => env('WEFTKIT_PORT', '5432'), 'database' => env('WEFTKIT_DB', 'mydb'), 'username' => env('WEFTKIT_USER', 'app_user'), 'password' => env('WEFTKIT_PASS', ''), 'charset' => 'utf8', 'prefix' => '', 'schema' => 'public', 'sslmode' => env('WEFTKIT_SSLMODE', 'prefer'), ], // ... other connections ],
.env
bashDB_CONNECTION=weftkit WEFTKIT_HOST=localhost WEFTKIT_PORT=5432 WEFTKIT_DB=mydb WEFTKIT_USER=app_user WEFTKIT_PASS=secret WEFTKIT_SSLMODE=require
Eloquent Model
php<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; class User extends Model { protected $connection = 'weftkit'; protected $table = 'users'; protected $fillable = ['name', 'email', 'age']; protected $casts = [ 'age' => 'integer', 'created_at' => 'datetime', ]; public function orders(): HasMany { return $this->hasMany(Order::class); } }
Artisan Migration
php<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::connection('weftkit')->create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->unsignedInteger('age')->default(0); $table->timestamps(); }); } public function down(): void { Schema::connection('weftkit')->dropIfExists('users'); } };
bashphp artisan migrate --database=weftkit
Eloquent Queries
phpuse App\Models\User; // Create $user = User::create(['name' => 'Alice', 'email' => 'alice@example.com', 'age' => 30]); // Find $user = User::find(1); $user = User::where('email', 'alice@example.com')->firstOrFail(); // Filter and order $adults = User::where('age', '>', 18) ->orderBy('name') ->get(); // Eager loading $users = User::with('orders')->where('age', '>', 18)->get(); // Update $user->update(['age' => 31]); // Delete $user->delete();
6. Laravel — WeftKitDoc via MongoDB
Install the Laravel MongoDB package:
bashcomposer require mongodb/laravel-mongodb
Register the service provider in config/app.php (Laravel 10 and below):
php'providers' => [ // ... MongoDB\Laravel\MongoDBServiceProvider::class, ],
MongoDB Connection in config/database.php
php'mongodb' => [ 'driver' => 'mongodb', 'host' => env('MONGO_HOST', 'localhost'), 'port' => env('MONGO_PORT', 27017), 'database' => env('MONGO_DB', 'mydb'), 'username' => env('MONGO_USER', ''), 'password' => env('MONGO_PASS', ''), 'options' => [], ],
.env
bashMONGO_HOST=localhost MONGO_PORT=27017 MONGO_DB=mydb MONGO_USER=app_user MONGO_PASS=secret
MongoDB Eloquent Model
php<?php namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Article extends Model { protected $connection = 'mongodb'; protected $collection = 'articles'; protected $fillable = ['title', 'author', 'tags', 'views']; protected $casts = [ 'tags' => 'array', 'views' => 'integer', ]; }
MongoDB Query Builder
phpuse App\Models\Article; // Create Article::create([ 'title' => 'Getting Started', 'author' => 'Alice', 'tags' => ['database', 'weftkit'], 'views' => 0, ]); // Find $article = Article::where('author', 'Alice')->first(); // Filter with MongoDB operators $popular = Article::where('views', '>', 1000)->orderBy('views', 'desc')->get(); // Update Article::where('author', 'Bob')->increment('views', 10); // Aggregation via query builder $stats = Article::raw(function ($collection) { return $collection->aggregate([ ['$group' => ['_id' => '$author', 'total' => ['$sum' => '$views']]], ['$sort' => ['total' => -1]], ]); });
7. Laravel — WeftKitMem (Redis)
config/database.php Redis Connection
php'redis' => [ 'client' => env('REDIS_CLIENT', 'predis'), 'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_DB', 0), ], 'cache' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_CACHE_DB', 1), ], ],
.env
bashREDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD=secret REDIS_CLIENT=predis CACHE_DRIVER=redis SESSION_DRIVER=redis
Cache Facade
phpuse Illuminate\Support\Facades\Cache; // Store with TTL Cache::store('redis')->put('featured_products', $products, now()->addHours(2)); // Retrieve $products = Cache::store('redis')->get('featured_products'); // Remember pattern (fetch + cache in one step) $user = Cache::store('redis')->remember('user:42', 3600, function () { return User::find(42); }); // Invalidate Cache::store('redis')->forget('user:42');
Redis Facade
phpuse Illuminate\Support\Facades\Redis; // Direct commands Redis::set('session:abc123', 'user_42', 'EX', 1800); $value = Redis::get('session:abc123'); // Hash Redis::hmset('user:42', ['name' => 'Alice', 'plan' => 'pro']); $name = Redis::hget('user:42', 'name'); // Pipeline Redis::pipeline(function ($pipe) { $pipe->set('key:1', 'value_1'); $pipe->expire('key:1', 600); $pipe->incr('stats:requests'); });
Connection String Quick Reference
| Engine | Driver | Connection |
|---|---|---|
| WeftKitRel | PDO pgsql | pgsql:host=localhost;port=5432;dbname=mydb |
| WeftKitDoc | mongodb/mongodb | mongodb://app_user:secret@localhost:27017 |
| WeftKitMem | predis/predis | tcp://localhost:6379?password=secret |
| WeftKitGraph | laudis/neo4j-php-client | bolt://app_user:secret@localhost:7687 |
Next Steps
- Deployment — Start and configure WeftKit Standalone
- Security — Configure TLS, JWT, and mTLS for production
- Integration Guides — Other language guides
On this page