Skip to content
WeftKitBeta

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-pgsql and php-mongodb extensions 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

php
try {
    $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

bash
DB_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');
    }
};
bash
php artisan migrate --database=weftkit

Eloquent Queries

php
use 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:

bash
composer 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

bash
MONGO_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

php
use 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

bash
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=secret
REDIS_CLIENT=predis
CACHE_DRIVER=redis
SESSION_DRIVER=redis

Cache Facade

php
use 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

php
use 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