PHP code example of simsoft / fliq

1. Go to this page and download the library: Download simsoft/fliq library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

simsoft / fliq example snippets


use Simsoft\DB\Model;

class User extends Model
{
    protected string $table = 'user';
    protected array $fillable = ['name', 'email', 'status'];
}

// Query with fluent builder
$users = User::find()
    ->where('status', 'active')
    ->with('posts.comments')  // nested eager loading
    ->orderBy('name')
    ->get();

// CRUD
$user = new User(['name' => 'John', 'email' => '[email protected]']);
$user->save();



use Simsoft\DB\Connection;

Connection::add('mysql', [
    'driver' => 'mysqli',
    'host' => 'localhost',
    'database' => 'my_app',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8mb4',
]);

use Simsoft\DB\Model;
use Simsoft\DB\Relation;

class Post extends Model
{
    protected string $table = 'post';
    protected array $fillable = ['title', 'content', 'user_id'];

    public function author(): Relation
    {
        return $this->hasOne(User::class, ['id' => 'user_id']);
    }

    public function comments(): Relation
    {
        return $this->hasMany(Comment::class, ['post_id' => 'id']);
    }
}

// Find by primary key
$post = Post::findByPk(1);

// Query with conditions
$posts = Post::find()
    ->where('status', 'published')
    ->with('author', 'comments')
    ->orderBy('created_at', 'DESC')
    ->limit(10)
    ->get();

// Create
$post = new Post(['title' => 'Hello', 'content' => 'World']);
$post->save();

// Update
$post->title = 'Updated';
$post->save();

// Delete
$post->delete();

// 4 queries total, regardless of record count
$users = User::find()->with('posts.comments.author')->get();

$users = User::find()
    ->when($search !== null, fn($q) => $q->like('name', "%$search%"))
    ->unless($isAdmin, fn($q) => $q->where('published', true))
    ->get();

// Auto JSON extraction via -> notation (works in where, in, orderBy, etc.)
User::find()->where('preferences->dining->meal', 'salad')->get();
User::find()->in('preferences->dining->meal', ['pasta', 'salad'])->get();
User::find()->orderBy('meta->score', 'DESC')->get();

// JSON methods
User::find()->jsonContains('tags', 'php')->get();            // array contains value
User::find()->jsonNotContains('tags', 'java')->get();        // array excludes value
User::find()->jsonHas('meta->address')->get();               // key exists
User::find()->jsonMissing('meta->foo')->get();               // key missing
User::find()->jsonLength('tags', '>', 2)->get();             // array length

// Aliases (whereJson* style)
User::find()->whereJsonContains('tags', 'php')->get();
User::find()->whereJsonDoesntContain('tags', 'java')->get();
User::find()->whereJsonContainsKey('meta->address')->get();
User::find()->whereJsonDoesntContainKey('meta->foo')->get();
User::find()->whereJsonLength('tags', '>', 2)->get();

// Match ANY column (OR logic)
User::find()->whereAny(['name', 'email', 'phone'], 'like', '%john%')->get();
// → WHERE (name LIKE ? OR email LIKE ? OR phone LIKE ?)

// Match ALL columns (AND logic)
Post::find()->whereAll(['title', 'body'], 'like', '%Laravel%')->get();
// → WHERE (title LIKE ? AND body LIKE ?)

// Match NONE of the columns
Post::find()->whereNone(['title', 'body'], 'like', '%spam%')->get();
// → WHERE NOT (title LIKE ? OR body LIKE ?)

User::transaction(function () {
    $user = new User(['name' => 'John', 'email' => '[email protected]']);
    $user->save();

    $post = new Post(['user_id' => $user->id, 'title' => 'First Post']);
    $post->save();

    return true; // commit
});
// Return false (or don't return true) to roll back

$driver->transaction(function () {
    /* FOR UPDATE — exclusive lock for safe concurrent writes */
    $job = Job::find()->where('status', 'pending')->limit(1)->forUpdate()->first();
    $job->update(['status' => 'processing']);
    return true;
});

/* FOR UPDATE SKIP LOCKED — job queue pattern (skip rows locked by other workers) */
$job = Job::find()->where('status', 'pending')->forUpdateSkipLocked()->first();

class User extends Model
{
    use SoftDeletes, Timestamps;
    protected string $table = 'user';
}

$user->delete();    // sets deleted_at
$user->restore();   // clears deleted_at
User::withTrashed()->get(); // 

// Register event listeners
User::on('creating', function (User $user) {
    $user->slug = strtolower($user->name);
});

User::on('deleting', function (User $user) {
    if ($user->role === 'admin') return false; // cancel deletion
});

// Observer class
User::observe(new AuditObserver());

use Simsoft\DB\Cache\QueryCache;
use Simsoft\DB\Cache\ArrayCache;

QueryCache::setDriver(new ArrayCache());

// Cache results for 60 seconds
$users = User::find()->where('active', 1)->cache(60)->get();

Connection::add('mysql', [
    'driver' => 'mysqli',
    'database' => 'myapp',
    'read' => ['host' => 'replica.db.internal'],
    'write' => ['host' => 'primary.db.internal'],
]);
// SELECT auto-routes to read, INSERT/UPDATE/DELETE to write

// N+1 detection
QueryMonitor::enable();

// Query logging with timing
QueryLogger::enable();
$queries = QueryLogger::getQueries();
$slowest = QueryLogger::getSlowestQuery();

// Index advisor
IndexAdvisor::suggestSQL();

// EXPLAIN query plans
$plan = User::find()->where('role', 'admin')->explain(analyze: true);

use Simsoft\DB\Generator\ModelGenerator;

ModelGenerator::fromTable('user')->namespace('App\\Models')->generate();
ModelGenerator::generateAll(namespace: 'App\\Models');

use Simsoft\DB\Generator\ObserverGenerator;

ObserverGenerator::forModel('User')->generate();