PHP code example of webrium / foxql

1. Go to this page and download the library: Download webrium/foxql 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/ */

    

webrium / foxql example snippets


use Foxdb\DB;

DB::addConnection([
    'driver'           => 'mysql',       // 'mysql' | 'pgsql' | 'sqlite'
    'host'             => '127.0.0.1',
    'port'             => '3306',
    'database'         => 'my_db',
    'username'         => 'root',
    'password'         => 'secret',
    'charset'          => 'utf8mb4',
    'throw_exceptions' => true,          // default: true
]);

DB::addConnection([
    'driver'   => 'sqlite',
    'database' => '/var/data/my_app.sqlite',
]);

DB::addConnection([...], 'main');
DB::addConnection([...], 'analytics');

DB::use('analytics');               // subsequent calls use this connection
DB::use('main');                    // switch back

DB::connection('analytics');        // get the raw Connection instance

// Get all rows — returns a Collection of stdClass objects
$users = DB::table('users')->get();

foreach ($users as $user) {
    echo $user->name;
}

// Get the first matching row — returns stdClass or false if nothing matches
$user = DB::table('users')->where('email', '[email protected]')->first();

if ($user) {
    echo $user->name;
}

// Get a single column value from the first matching row
$email = DB::table('users')->where('id', 5)->value('email');

// Get a flat array of values from a single column
$names = DB::table('users')->pluck('name');
// → ['Alice', 'Bob', 'Carol']

// Get an array keyed by another column — useful for dropdowns
$nameById = DB::table('users')->pluck('name', 'id');
// → [1 => 'Alice', 2 => 'Bob']

// Find a row by its primary key
$user = DB::table('users')->find(5);

// Select only certain columns
$users = DB::table('users')->select('id', 'name', 'email')->get();

// Select a raw expression
$stats = DB::table('orders')
    ->selectRaw('COUNT(*) as total, SUM(amount) as revenue')
    ->where('status', 'paid')
    ->first();

// Remove duplicate rows
$countries = DB::table('users')->distinct()->pluck('country');

// Process 200 rows at a time
DB::table('users')->orderBy('id')->chunk(200, function ($users) {
    foreach ($users as $user) {
        // process each user
    }

    // Return false from the callback to stop chunking early
});

// Simpler iteration with each()
DB::table('users')->orderBy('id')->each(function ($user) {
    // called once per row
});

->where('active', 1)                    // WHERE active = 1
->where('age', '>', 18)                 // WHERE age > 18
->where('role', '!=', 'banned')         // WHERE role != 'banned'
->orWhere('role', 'admin')              // OR role = 'admin'
->whereNot('status', 'deleted')         // WHERE status != 'deleted'

->whereIn('id', [1, 2, 3])
->whereNotIn('status', ['banned', 'pending'])
->orWhereIn('role', ['admin', 'mod'])

->whereBetween('age', 18, 65)
->whereNotBetween('score', 0, 10)

->whereNull('deleted_at')       // only rows where deleted_at IS NULL
->whereNotNull('verified_at')   // only rows where verified_at is set

->whereRaw('YEAR(created_at) = ? AND MONTH(created_at) = ?', [2024, 3])

->whereDate('created_at', '=', '2024-01-15')    // full date match
->whereYear('created_at', '=', 2024)
->whereMonth('created_at', '=', 1)
->whereDay('created_at', '=', 15)
->whereTime('created_at', '>', '08:00:00')

->whereColumn('updated_at', '>', 'created_at')

// WHERE (role = 'admin' OR role = 'mod') AND active = 1
DB::table('users')
    ->where(function ($q) {
        $q->where('role', 'admin')->orWhere('role', 'mod');
    })
    ->where('active', 1)
    ->get();

// WHERE EXISTS (SELECT 1 FROM orders WHERE orders.user_id = users.id)
->whereExists(function ($q) {
    $q->table('orders')->whereColumn('user_id', 'users.id');
})

->is('active', 1)       // same as where('active', 1)
->true('active')        // same as where('active', 1)
->false('active')       // same as where('active', 0)
->null('deleted_at')    // same as whereNull('deleted_at')
->notNull('email')      // same as whereNotNull('email')
->in('id', [1,2,3])     // same as whereIn('id', [...])
->notIn('id', [4,5])    // same as whereNotIn('id', [...])
->like('name', '%ali%') // WHERE name LIKE '%ali%'
->and('age', '>', 18)   // same as where()
->or('role', 'admin')   // same as orWhere()

// INNER JOIN — only rows that have a match in both tables
DB::table('users')
    ->join('orders', 'orders.user_id', '=', 'users.id')
    ->select('users.name', 'orders.total', 'orders.status')
    ->get();

// LEFT JOIN — all users, even those with no orders
DB::table('users')
    ->leftJoin('orders', 'orders.user_id', '=', 'users.id')
    ->select('users.name', 'orders.total')
    ->get();

->rightJoin('table', 'a', '=', 'b')
->crossJoin('tags')

// Join against a subquery
->joinSub($subQuery, 'alias', 'alias.user_id', '=', 'users.id')

// Sort results
->orderBy('name')                   // ASC by default
->orderBy('created_at', 'desc')
->orderByDesc('score')              // shorthand for desc
->latest()                          // ORDER BY created_at DESC
->oldest()                          // ORDER BY created_at ASC
->inRandomOrder()                   // ORDER BY RAND() — useful for random picks

// Sort by multiple columns
->orderBy('role')->orderBy('name', 'desc')

// Group results and filter groups
->groupBy('country')
->having('total_users', '>', 100)
->havingRaw('COUNT(*) > 100')

// Limit the number of results
->limit(10)
->offset(20)
->take(10)->skip(20)    // aliases — take and skip are identical to limit and offset

$count    = DB::table('users')->count();
$active   = DB::table('users')->where('active', 1)->count();
$revenue  = DB::table('orders')->where('status', 'paid')->sum('total');
$avgScore = DB::table('users')->avg('score');
$lowest   = DB::table('products')->min('price');
$highest  = DB::table('products')->max('price');

// Check if any matching row exists
$exists = DB::table('users')->where('email', '[email protected]')->exists();  // bool

// Insert a single row
DB::table('users')->insert([
    'name'  => 'Ali',
    'email' => '[email protected]',
]);

// Insert and get the auto-increment ID back
$id = DB::table('users')->insertGetId([
    'name'  => 'Ali',
    'email' => '[email protected]',
]);

// Insert multiple rows in one query
DB::table('users')->insertBatch([
    ['name' => 'Ali',  'email' => '[email protected]'],
    ['name' => 'Sara', 'email' => '[email protected]'],
    ['name' => 'Reza', 'email' => '[email protected]'],
]);

// Update matching rows — returns the number of affected rows
$affected = DB::table('users')
    ->where('id', 1)
    ->update(['name' => 'New Name', 'updated_at' => date('Y-m-d H:i:s')]);

// Increment or decrement a numeric column
DB::table('users')->where('id', 1)->increment('login_count');
DB::table('users')->where('id', 1)->increment('score', 10);
DB::table('users')->where('id', 1)->decrement('credits', 5);

// You can also update other columns at the same time
DB::table('users')->where('id', 1)->increment('score', 10, [
    'last_activity' => date('Y-m-d H:i:s'),
]);

// Update if found, insert if not
DB::table('settings')->updateOrInsert(
    ['key' => 'theme'],             // lookup condition
    ['value' => 'dark']             // value to set
);

// Delete matching rows
DB::table('users')->where('id', $id)->delete();

// Delete with multiple conditions
DB::table('sessions')
    ->where('user_id', $userId)
    ->where('created_at', 'delete();

// Remove all rows from the table
DB::table('cache')->truncate();

$page   = (int) ($_GET['page'] ?? 1);
$result = DB::table('posts')
    ->where('published', 1)
    ->orderBy('created_at', 'desc')
    ->paginate(15, $page);

// Use in an API response
return [
    'meta' => [
        'total'        => $result->total,
        'current_page' => $result->current_page,
        'last_page'    => $result->last_page,
    ],
    'data' => $result->data->toArray(),
];

// Select — returns array of stdClass
$rows = DB::select('SELECT * FROM users WHERE active = ? AND age > ?', [1, 18]);

// Select a single row
$user = DB::selectOne('SELECT * FROM users WHERE id = ?', [$id]);

// Insert
DB::insert('INSERT INTO logs (level, message) VALUES (?, ?)', ['info', 'User logged in']);

// Insert and get the new ID
$id = DB::insertGetId('INSERT INTO users (name) VALUES (?)', ['Ali']);

// Update
$affected = DB::update('UPDATE users SET active = ? WHERE last_login < ?', [0, '2023-01-01']);

// Delete
$deleted = DB::delete('DELETE FROM logs WHERE created_at < ?', ['2023-01-01']);

// Any statement (DDL, etc.)
DB::statement('ALTER TABLE users ADD COLUMN bio TEXT NULL');

// Raw expression inside a query
$stats = DB::table('products')
    ->select(DB::raw('category_id, COUNT(*) as count, AVG(price) as avg_price'))
    ->groupBy('category_id')
    ->having(DB::raw('COUNT(*)'), '>', 5)
    ->get();

DB::transaction(function () use ($fromId, $toId, $amount) {
    DB::table('accounts')->where('id', $fromId)->decrement('balance', $amount);
    DB::table('accounts')->where('id', $toId)->increment('balance', $amount);
    DB::table('transfers')->insert([
        'from_id' => $fromId,
        'to_id'   => $toId,
        'amount'  => $amount,
    ]);
});

DB::beginTransaction();

try {
    // ... your operations ...
    DB::commit();
} catch (\Throwable $e) {
    DB::rollBack();
    throw $e;
}

DB::inTransaction(); // bool — check if currently inside a transaction

// See the SQL and bindings without executing
$sql      = DB::table('users')->where('active', 1)->orderBy('name')->toSql();
$bindings = DB::table('users')->where('active', 1)->orderBy('name')->getBindings();

// Dump SQL and bindings to output, then continue execution
DB::table('users')->where('active', 1)->dump()->get();

// Dump SQL and bindings to output, then stop (useful during development)
DB::table('users')->where('active', 1)->dd();

use Foxdb\Eloquent\Model;

class User extends Model
{
    // The database table. If not set, FoxDB auto-derives it:
    // User → users, UserProfile → user_profiles (snake_case + plural s)
    protected string $table = 'users';

    // The primary key column. Defaults to 'id'.
    protected string $primaryKey = 'id';

    // Columns that may be set via create() or fill().
    // Only columns listed here can be mass-assigned.
    protected array $fillable = ['name', 'email', 'age', 'is_active'];

    // Alternatively, use $guarded to blocklist instead of allowlist.
    // An empty guarded array means everything is allowed.
    // protected array $guarded = [];

    // Columns excluded from toArray() and toJson() output.
    // Use this for passwords, tokens, and other sensitive fields.
    protected array $hidden = ['password', 'remember_token'];

    // Set to false if the table does not have created_at / updated_at columns.
    protected bool $timestamps = true;

    // Automatically cast column values to PHP types on read.
    protected array $casts = [
        'is_active' => 'bool',
        'age'       => 'int',
        'score'     => 'float',
        'settings'  => 'array',    // stored as JSON, returned as array
        'born_at'   => 'datetime', // returned as a DateTime object
    ];

    // Use a specific named connection instead of the default.
    protected ?string $connection = null;
}

// $fillable = ['name', 'email'] — 'role' is blocked
User::create(['name' => 'Ali', 'email' => '[email protected]', 'role' => 'admin']);
// role is silently ignored

// If you need to bypass the guard (e.g. in a seeder), use forceFill()
$user = new User();
$user->forceFill(['name' => 'Ali', 'role' => 'admin'])->save();

// create() fills, saves, and returns the new model
$user = User::create(['name' => 'Ali', 'email' => '[email protected]', 'age' => 25]);
echo $user->id;          // the auto-increment ID from the database
echo $user->created_at;  // set automatically

// Alternatively, use new + save()
$user        = new User();
$user->name  = 'Ali';
$user->email = '[email protected]';
$user->save();

// All rows — returns a Collection
$users = User::all();

// By primary key
$user = User::find(1);          // returns User or null
$user = User::findOrFail(1);    // returns User or throws ModelNotFoundException

// First matching row
$user = User::where('email', '[email protected]')->first();
$user = User::firstWhere('email', '[email protected]');   // shorthand

// You can chain any Builder method
$admins = User::where('role', 'admin')
              ->where('active', 1)
              ->orderBy('name')
              ->get();

// Aggregates
$count = User::where('active', 1)->count();
$avg   = User::avg('score');

// Check existence
$exists = User::exists(['email' => '[email protected]']); // bool

// Change attributes and call save() — only the changed columns are written
$user       = User::findOrFail(1);
$user->name = 'New Name';
$user->save();

// Mass update via query — affects all matching rows
User::where('active', 0)->update(['score' => 0]);

// Delete a single model instance
$user = User::findOrFail(1);
$user->delete();

// Delete all rows matching a condition
User::where('created_at', 'delete();

// fresh() returns a new instance fetched from the DB, leaving the original untouched
$fresh = $user->fresh();

// refresh() updates the current instance in place
$user->refresh();

$user = User::find(1);  // loaded: name = 'Ali'

$user->isDirty();        // false — nothing has changed yet

$user->name = 'New Name';

$user->isDirty();        // true
$user->isDirty('name');  // true
$user->isDirty('email'); // false — email was not changed

$user->getDirty();       // ['name' => 'New Name']

$user->save();           // UPDATE users SET name = ? WHERE id = ?
                         // email is NOT 

class User extends Model
{
    protected array $casts = [
        'is_active' => 'bool',
        'age'       => 'int',
        'score'     => 'float',
        'settings'  => 'array',
        'born_at'   => 'datetime',
    ];
}

$user = User::find(1);

$user->is_active;  // true or false, not "1" or "0"
$user->age;        // 25 (int), not "25" (string)
$user->settings;   // ['theme' => 'dark', 'lang' => 'fa'] — decoded from JSON
$user->born_at;    // DateTime object — can call ->format(), ->diff(), etc.

// Casts work in reverse on write — the array is JSON-encoded before saving
$user->settings = ['theme' => 'light'];
$user->save();     // stores '{"theme":"light"}' in the database

use Foxdb\Eloquent\Concerns\HasSoftDeletes;

class Post extends Model
{
    use HasSoftDeletes;
}

$post = Post::find(1);
$post->delete();           // sets deleted_at — the row stays in the database

Post::find(1);             // returns null — soft-deleted rows are excluded by default
Post::count();             // does NOT count soft-deleted rows

$post->trashed();          // true — check if this instance has been soft-deleted

// Include soft-deleted rows in a query
$all = Post::withTrashed()->get();
$all = Post::withTrashed()->find(1);  // returns the soft-deleted post

// Query only the soft-deleted rows
$deleted = Post::onlyTrashed()->get();

// Restore a soft-deleted record
Post::withTrashed()->find(1)->restore();  // clears deleted_at

class BaseModel extends Model
{
    use HasSoftDeletes;
}

class Post extends BaseModel
{
    protected string $table = 'posts';
}

// The scope is applied correctly — Post inherits from BaseModel
Post::find(1);  // still excludes soft-deleted rows

class User extends Model
{
    public function posts(): HasMany
    {
        // hasMany(related model, foreign key on related table, local key)
        return $this->hasMany(Post::class, 'user_id', 'id');
    }
}

public function profile(): HasOne
{
    return $this->hasOne(Profile::class, 'user_id', 'id');
}

class Post extends Model
{
    public function author(): BelongsTo
    {
        // belongsTo(related model, foreign key on THIS table, owner key on related table)
        return $this->belongsTo(User::class, 'user_id', 'id');
    }
}

public function roles(): BelongsToMany
{
    // belongsToMany(related, pivot table, FK for this model, FK for related model)
    return $this->belongsToMany(Role::class, 'user_role', 'user_id', 'role_id');
}

public function comments(): HasManyThrough
{
    return $this->hasManyThrough(
        Comment::class,  // the final model you want
        Post::class,     // the intermediate model
        'user_id',       // FK on posts pointing to users
        'post_id',       // FK on comments pointing to posts
        'id',            // local key on users
        'id',            // local key on posts
    );
}

$user = User::find(1);

$posts   = $user->posts;    // runs a query, returns Collection
$posts   = $user->posts;    // uses the cached result — no second query

$author  = $post->author;   // User|null
$profile = $user->profile;  // Profile|null

// Add a role to a user
$user->roles()->attach(3);
$user->roles()->attach([3, 5, 7]);

// Add with data on the pivot row
$user->roles()->attach(3, ['granted_at' => date('Y-m-d')]);

// Remove a role
$user->roles()->detach(3);
$user->roles()->detach();       // remove all

// Sync — attach the given IDs and detach everything else
$user->roles()->sync([3, 5]);

// Include pivot columns when loading the relation
$roles = $user->roles()->withPivot('granted_at', 'expires_at')->get();
echo $roles->first()->pivot->granted_at;

// Set the foreign key by passing the related model (does not save automatically)
$post->author()->associate($user);
$post->save();

// Clear the foreign key
$post->author()->dissociate();
$post->save();

// Without eager loading — runs 1 + N queries
$users = User::all();
foreach ($users as $user) {
    echo $user->posts->count(); // query per user!
}

// With eager loading — runs exactly 2 queries
$users = User::with('posts')->get();
foreach ($users as $user) {
    echo $user->posts->count(); // no query — already loaded
}

$users = User::with('posts', 'profile', 'roles')->get();

$users = User::with([
    'posts' => fn($query) => $query->where('published', 1)->orderBy('created_at', 'desc')
])->get();

$data = User::with('posts')->get()->toArray();
// $data[0]['posts'] → array of post arrays

class User extends Model
{
    // Scope to filter only active users
    public function scopeActive(Builder $q): Builder
    {
        return $q->where('is_active', 1);
    }

    // Scope with a parameter
    public function scopeRole(Builder $q, string $role): Builder
    {
        return $q->where('role', $role);
    }

    // Scope for recent records
    public function scopeRecent(Builder $q, int $days = 7): Builder
    {
        return $q->where('created_at', '>=', date('Y-m-d', strtotime("-{$days} days")));
    }
}

// Use the scope — drop the 'scope' prefix and call as static
User::active()->get();
User::role('admin')->get();
User::recent(30)->get();

// Scopes are fully chainable with each other and with other Builder methods
User::active()
    ->role('mod')
    ->recent()
    ->orderBy('name')
    ->paginate(20, $page);

$user = User::with('posts')->find(1);

$arr  = $user->toArray();   // ['id' => 1, 'name' => 'Ali', 'posts' => [...], ...]
$json = $user->toJson();    // same data as a JSON string
$json = (string) $user;     // identical to toJson()

json_encode($user);         // also works — Model implements JsonSerializable

$users = User::with('posts')->get();

$arr  = $users->toArray();       // array of arrays — correct
$json = json_encode($users);     // correct

// Use in an API response
return ['ok' => true, 'users' => $users->toArray()];

$users = User::all();  // Collection

// Basic access
$users->count();
$users->isEmpty();
$users->isNotEmpty();
$users->first();
$users->first(fn($u) => $u->role === 'admin');   // first matching
$users->last();
$users->get(2);         // item at index 2, null if missing
$users->contains('role', 'admin');
$users->contains(fn($u) => $u->age > 18);

// Iteration — works like a normal array
foreach ($users as $user) {
    echo $user->name;
}
$users[0];              // ArrayAccess read

// Filtering and transformation
$active   = $users->filter(fn($u) => $u->active);
$inactive = $users->reject(fn($u) => $u->active);   // inverse of filter
$names    = $users->map(fn($u) => (object)['name' => strtoupper($u->name)]);

$users->each(fn($u, $index) => processUser($u));
// Return false from the callback to stop early

// Sorting
$byName   = $users->sortBy('name');
$byScore  = $users->sortByDesc('score');

// Slicing
$first5   = $users->take(5);
$after10  = $users->skip(10);
$unique   = $users->unique('email');   // first occurrence wins
$reversed = $users->reverse();
$merged   = $users->merge($otherCollection);

// Split into chunks — returns an array of Collections
$chunks = $users->chunk(100);

// Extracting data
$names    = $users->pluck('name');               // ['Ali', 'Sara', ...]
$nameById = $users->pluck('name', 'id');         // [1 => 'Ali', 2 => 'Sara']
$byId     = $users->keyBy('id');                 // plain array keyed by id
$grouped  = $users->groupBy('role');             // plain array grouped by role value

// Aggregates — operate on a column across all items
$total    = $users->sum('score');
$average  = $users->avg('score');
$lowest   = $users->min('score');
$highest  = $users->max('score');

// Serialization
$arr  = $users->toArray();       // array of arrays — uses Model::toArray() per item
$json = $users->toJson();
$json = json_encode($users);     // identical
(string) $users;                 // pretty-printed JSON

use Foxdb\Schema;
use Foxdb\Schema\Blueprint;

Schema::create('users', function (Blueprint $table) {
    $table->id();                                      // BIGINT AUTO_INCREMENT PRIMARY KEY

    // String columns
    $table->string('name');                            // VARCHAR(255)
    $table->string('email', 255)->unique();
    $table->char('code', 10);
    $table->text('bio')->nullable();
    $table->mediumText('content')->nullable();
    $table->longText('body')->nullable();

    // Numeric columns
    $table->integer('age')->default(0);
    $table->bigInteger('views')->default(0);
    $table->tinyInteger('status')->default(1);
    $table->float('score', 8, 2)->nullable();
    $table->decimal('price', 10, 2)->default(0);

    // Boolean
    $table->boolean('is_active')->default(true);

    // Special types
    $table->json('settings')->nullable();              // stored as TEXT/JSON
    $table->enum('role', ['admin', 'user', 'mod'])->default('user');
    $table->uuid('uuid');
    $table->binary('data')->nullable();

    // Dates and times
    $table->date('born_at')->nullable();
    $table->time('opens_at')->nullable();
    $table->dateTime('published_at')->nullable();
    $table->timestamp('last_login')->nullable();

    // Convenience shortcuts
    $table->timestamps();                              // adds created_at + updated_at
    $table->softDeletes();                             // adds deleted_at

    // Foreign keys
    $table->foreignId('category_id');                  // BIGINT UNSIGNED NOT NULL
    $table->foreignIdFor(Category::class);             // derives column from model

    // Indexes
    $table->index('role');
    $table->index(['first_name', 'last_name'], 'idx_full_name');
    $table->unique(['tenant_id', 'email']);
    $table->primary(['tenant_id', 'user_id']);         // composite primary key

    // Foreign key constraints
    $table->foreign('category_id')
          ->references('id')
          ->on('categories')
          ->cascadeOnDelete();
});

Schema::table('users', function (Blueprint $table) {
    // Add a new column (nullable so existing rows are not affected)
    $table->integer('score')->nullable()->after('email')->change();

    // Rename a column
    $table->renameColumn('bio', 'about');

    // Remove columns
    $table->dropColumn('old_field');
    $table->dropColumn(['field_a', 'field_b']);

    // Remove indexes and constraints
    $table->dropIndex('idx_name');
    $table->dropUnique('idx_email');
    $table->dropForeign('fk_category_id');
});

Schema::drop('users');                          // drop the table (fails if it doesn't exist)
Schema::dropIfExists('users');                  // safe version — no error if missing
Schema::rename('old_table', 'new_table');

Schema::hasTable('users');                      // bool — check if table exists
Schema::hasColumn('users', 'email');            // bool — check if column exists
Schema::getColumnNames('users');                // array — all column names

use Foxdb\Migrations\Migration;
use Foxdb\Schema;
use Foxdb\Schema\Blueprint;

class CreateUsersTable extends Migration
{
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->boolean('is_active')->default(true);
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('users');
    }
}

use Foxdb\Migrations\Migrator;

// Point the Migrator at the folder containing your migration files
$migrator = new Migrator('/path/to/migrations');

// Run all migrations that have not been run yet
$migrator->run();

// Run at most 3 pending migrations
$migrator->run(3);

// Roll back the last batch of migrations
$migrator->rollback();

// Roll back the last 2 batches
$migrator->rollback(2);

// Roll back everything — brings the database back to a blank state
$migrator->reset();

// Reset and then run everything — useful for refreshing a dev database
$migrator->refresh();

// Check what has and hasn't been run yet
$migrator->status();               // array of migration status

// Check if anything is pending
if ($migrator->hasPendingMigrations()) {
    echo "Database is not up to date.";
}

// Enable logging before running your queries
DB::enableQueryLog();

$users = User::where('active', 1)->with('posts')->get();
$count = DB::table('orders')->where('status', 'paid')->count();

// Retrieve the log
$log = DB::getQueryLog();  // array of QueryLogEntry objects

foreach ($log as $entry) {
    echo $entry->sql;       // SELECT * FROM `users` WHERE `active` = ?
    echo $entry->time;      // execution time in milliseconds
    var_dump($entry->bindings);
}

// Shortcuts
DB::getLastQuery();                   // the most recent QueryLogEntry
DB::getQueryCount();                  // total number of queries run
DB::getTotalQueryTime();              // sum of all execution times in ms
DB::getSlowQueries(50.0);            // all queries that took more than 50ms

DB::disableQueryLog();
DB::flushQueryLog();                  // clear the log without disabling it

DB::beforeQuery(function (string $sql, array $bindings) {
    // Called just before each query is executed
    $this->logger->debug('Running query', ['sql' => $sql]);
});

DB::afterQuery(function (string $sql, array $bindings, float $timeMs) {
    // Called after each query completes
    if ($timeMs > 100) {
        $this->logger->warning('Slow query detected', ['sql' => $sql, 'time' => $timeMs]);
    }
});

use Foxdb\Exceptions\QueryException;
use Foxdb\Exceptions\DatabaseException;
use Foxdb\Exceptions\ModelNotFoundException;

// findOrFail() throws ModelNotFoundException when no row matches
try {
    $user = User::findOrFail(999);
} catch (ModelNotFoundException $e) {
    // return a 404 response
}

// QueryException wraps any PDO error — gives you the SQL and bindings
try {
    DB::table('users')->where('nonexistent_column', 1)->get();
} catch (QueryException $e) {
    echo $e->getSql();              // the compiled SQL
    echo $e->getErrorCode();        // the database error code
    echo $e->getFormattedMessage(); // full formatted error string
    var_dump($e->getParams());      // the bindings array
}