PHP code example of gemvc / library

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

    

gemvc / library example snippets


// 1. OpenSwoole: Asynchronous, non-blocking I/O
$server = new \OpenSwoole\HTTP\Server('0.0.0.0', 9501);
$server->set([
    'worker_num' => 4,
    'max_request' => 1000,
    'enable_coroutine' => true
]);

// 2. Database Cache: Automatic query caching
// Configure in .env:
// DB_CACHE_ENABLED=true
// DB_CACHE_TTL_SEC=3600
// DB_CACHE_MAX_QUERY_SIZE=1000

// 3. Connection Pooling: Efficient database connections
// Configure in .env:
// MIN_DB_CONNECTION_POOL=2
// MAX_DB_CONNECTION_POOL=5
// DB_CONNECTION_MAX_AGE=3600

// Without these features:
// - Each request creates new DB connection
// - Queries execute every time
// - Resources are wasted

// With GEMVC's performance trio:
// 1. OpenSwoole handles concurrent requests efficiently
// 2. DB Cache stores frequent query results
// 3. Connection Pooling reuses DB connections

// Result: Up to 10x performance improvement!

// Create an API endpoint
class UserController {
    public function getUsers(ApacheRequest $request) {
        // Smart type-safe value extraction
        $limit = $request->intValueGet('limit') ?: 10;
        
        $users = QueryBuilder::select('id', 'name')
            ->from('users')
            ->whereEqual('status', 'active')
            ->limit($limit)
            ->run();
            
        return (new JsonResponse())->success($users);
    }
}


// api/UserController.php

use Gemvc\Http\ApacheRequest;
use Gemvc\Http\JsonResponse;
use Gemvc\Database\QueryBuilder;

class UserController {
    
    public function getUsers(ApacheRequest $request) {
        // 1. Authenticate & authorize
        if (!$request->auth(['admin', 'system_manager'])) {
            return $request->returnResponse(); // Returns 401 or 403 with details
        }
        
        // 2. Validate query parameters
        if (!$request->defineGetSchema([
            '?limit' => 'int',
            '?page' => 'int',
            '?status' => 'string'
        ])) {
            return $request->returnResponse(); // Returns 400 with validation details
        }
        
        // 3. Type-safe parameter extraction
        $limit = $request->intValueGet('limit') ?: 10;
        $page = $request->intValueGet('page') ?: 1;
        $status = $request->get['status'] ?? 'active';
        
        // 4. Build and execute query
        $query = QueryBuilder::select('id', 'name', 'email', 'created_at')
            ->from('users')
            ->whereEqual('status', $status);
            
        // 5. Pagination
        $total = $query->count();
        $users = $query->limit($limit)
            ->offset(($page - 1) * $limit)
            ->run();
            
        // 6. Return structured response
        return (new JsonResponse())->success([
            'users' => $users,
            'pagination' => [
                'total' => $total,
                'page' => $page,
                'limit' => $limit,
                'pages' => ceil($total / $limit)
            ]
        ]);
    }
}

// From complex, error-prone code...
$stmt = $pdo->prepare("SELECT u.id, u.name FROM users WHERE status = ?");
$stmt->execute(['active']);

// To elegant, secure simplicity! 😍
$users = QueryBuilder::select('u.id', 'u.name')
    ->from('users')
    ->whereEqual('status', 'active')
    ->run();

// Build and execute a query with error handling
$users = QueryBuilder::select('id', 'name')
    ->from('users')
    ->whereEqual('status', 'active')
    ->run();

// If the query fails, check for errors
if ($users === false) {
    $error = QueryBuilder::getError();
    echo "Query failed: " . $error;
}

// Automatic protection against:
// ✓ SQL Injection
// ✓ XSS Attacks
// ✓ Path Traversal
// ✓ Shell Injection
// ✓ File Upload Vulnerabilities

// Military-grade file encryption in just 3 lines!
$file = new FileHelper($_FILES['upload']['tmp_name'], 'secure/file.dat');
$file->secret = $encryptionKey;
$file->moveAndEncrypt();  // AES-256-CBC + HMAC verification 🔐

// Consistent error responses with appropriate status codes
public function authorizeUser() {
    // Smart authentication with proper error responses
    $userId = $request->userId();
    
    // If invalid token or missing user ID, automatic 401/403 responses
    if (!$userId) {
        return $request->returnResponse(); // Already set with proper error info
    }
    
    // Type-safe value extraction with built-in validation
    $amount = $request->floatValueGet('amount');
    if (!$amount) {
        return $request->returnResponse(); // Returns 400 Bad Request with details
    }
    
    return $this->processTransaction($userId, $amount);
}

// Easy setup in .env file
// TOKEN_SECRET='your_jwt_secret_key'
// TOKEN_ISSUER='your_api_name'
// REFRESH_TOKEN_VALIDATION_IN_SECONDS=43200
// ACCESS_TOKEN_VALIDATION_IN_SECONDS=15800

// 1. Simple authentication - returns true/false
if (!$request->auth()) {
    // Already sets proper 401 response with details
    return $request->returnResponse();
}

// 2. Role-based authorization in one line
if (!$request->auth(['admin', 'system_manager'])) {
    // Already sets 403 response with specific role error
    // In this case only admin or system_manager user can perform this action!
    return $request->returnResponse();
}

// 3. Smart token extraction and verification
// - Automatically checks Authorization header
// - Validates expiration and signature
// - Sets detailed error messages on failure

// 4. Type-safe user information access with validation
$userId = $request->userId(); // Returns int or null with proper error response
$userRole = $request->userRole(); // Returns string or null with proper error response

// Same business logic, different server environments!

// --- APACHE/NGINX with PHP-FPM ---
function processUser($request) {
    if ($request->auth(['admin'])) {
        return (new JsonResponse())->success([
            'message' => 'Hello ' . $request->userId()
        ]);
    }
    return $request->returnResponse(); // Returns error response
}

// Apache handler
$request = new ApacheRequest(); // Handles traditional PHP request
$response = processUser($request->request);
$response->show(); // Output JSON

// --- OPENSWOOLE HIGH-PERFORMANCE SERVER ---
// In index.php (Swoole server startup)
$server = new \OpenSwoole\HTTP\Server('0.0.0.0', 9501);

// Set server configurations
$server->set([
    'worker_num' => 4,
    'max_request' => 1000,
    'enable_coroutine' => true,
    'document_root' => __DIR__,
    'enable_static_handler' => true
]);

// Handle each request
$server->on('request', function ($request, $response) {
    // Same code, different environment!
    $webserver = new SwooleRequest($request);
    $bootstrap = new SwooleBootstrap($webserver->request);
    $jsonResponse = $bootstrap->processRequest();
    
    $response->header('Content-Type', 'application/json');
    $response->end($jsonResponse->toJson());
});

$server->start();

// Dynamic class selection based on available extensions
$swooleClass = class_exists('\\OpenSwoole\\WebSocket\\Server') 
    ? '\\OpenSwoole\\WebSocket\\Server' 
    : (class_exists('\\Swoole\\WebSocket\\Server') 
        ? '\\Swoole\\WebSocket\\Server' 
        : null);

if (!$swooleClass) {
    die("Error: Neither OpenSwoole nor Swoole extensions are installed.");
}

// Create server with the appropriate class
$server = new $swooleClass('0.0.0.0', 9501);

// Runtime instance checking for method calls
function handleSwooleObject($swooleObject) {
    // Works with both OpenSwoole and Swoole objects
    if ($swooleObject instanceof \OpenSwoole\WebSocket\Server ||
        $swooleObject instanceof \Swoole\WebSocket\Server) {
        // Safe to use common methods
        $swooleObject->push(...);
    }
}

// Set up WebSocket server with advanced features
$server = new \OpenSwoole\WebSocket\Server('0.0.0.0', 9501);

// Initialize handler with scalability options
$handler = new SwooleWebSocketHandler([
    'connectionTimeout' => 300,
    'maxMessagesPerMinute' => 60,
    'heartbeatInterval' => 30,
    'redis' => [
        'enabled' => true,
        'host' => '127.0.0.1',
        'port' => 6379,
        'prefix' => 'websocket:'
    ]  // Scale across servers with automatic failover!
]);

// Register events and start server
$server->on('open', [$handler, 'onOpen']);
$server->on('message', [$handler, 'onMessage']);
$server->on('close', [$handler, 'onClose']);
$handler->registerHeartbeat($server);
$server->start();

// Define a table class for database interaction
// Note: This is NOT a Model layer (which will be added later)
// This is a database abstraction layer for direct table operations
class UserTable extends Table {
    // Database table properties matching columns
    public int $id;
    public string $username;
    public string $email;
    public string $password;
    public bool $is_active = true;
    public ?string $deleted_at = null;
    
    // Type mapping for database to PHP conversion
    protected array $_type_map = [
        'id' => 'int',
        'is_active' => 'bool',
        'deleted_at' => 'datetime'
    ];
    
    // Required constructor specifying the table name
    public function __construct() {
        parent::__construct('users');
    }
    
    // Custom database query methods
    public function findByEmail(string $email): ?self {
        return $this->select()
            ->where('email', $email)
            ->limit(1)
            ->run()[0] ?? null;
    }
}

// Database CRUD operations with fluent interface
// Create a new database record
$userTable = new UserTable();
$userTable->username = 'john_doe';
$userTable->email = '[email protected]';
$userTable->password = password_hash('secure123', PASSWORD_DEFAULT);
$result = $userTable->insertSingleQuery();

// Read records with fluent query building
$activeUserRecords = (new UserTable())
    ->select()
    ->where('is_active', true)
    ->whereNull('deleted_at')
    ->whereBetween('created_at', date('Y-m-d', strtotime('-30 days')), date('Y-m-d'))
    ->orderBy('username', true) // true = ascending order
    ->run();

// Update a record
$userRecord = (new UserTable())->selectById(1);
if ($userRecord) {
    $userRecord->email = '[email protected]';
    $userRecord->updateSingleQuery();
}

// Soft delete (sets deleted_at timestamp)
$userRecord->safeDeleteQuery();

// Restore soft-deleted record
$userRecord->restoreQuery();

// Hard delete
$userRecord->deleteSingleQuery();

// Pagination
$userTable = new UserTable();
$userTable->setPage($_GET['page'] ?? 1);
$userTable->limit(10);

$records = $userTable
    ->select()
    ->where('is_active', true)
    ->orderBy('created_at', false) // false = descending order
    ->run();

// Pagination metadata
$pagination = [
    'current_page' => $userTable->getCurrentPage(),
    'total_pages' => $userTable->getCount(),
    'total_records' => $userTable->getTotalCounts(),
    'per_page' => $userTable->getLimit()
];

// Define a class that extends Table
class UserTable extends Table {
    // Properties that match your database columns
    public int $id;  // Will become INT(11) AUTO_INCREMENT PRIMARY KEY
    public string $username;  // Will become VARCHAR(255)
    public string $email;  // Will become VARCHAR(320)
    public string $password;
    public ?string $bio = null;
    public bool $is_active = true;
    public string $created_at;
    
    // Type mapping for automatic conversion
    protected array $_type_map = [
        'id' => 'int',
        'is_active' => 'bool',
        'created_at' => 'datetime'
    ];
    
    // Constructor passes table name to parent
    public function __construct() {
        parent::__construct('users');
    }
}

// Create database table from the Table-derived class
$generator = new TableGenerator();

// Fluent interface for configuration
$generator
    // Add indexes
    ->addIndex('username', true)  // Unique index
    ->addIndex('email', true)     // Unique index
    
    // Add constraints
    ->setNotNull('username')
    ->setDefault('is_active', true)
    ->setDefault('created_at', 'CURRENT_TIMESTAMP')
    ->addCheck('username', 'LENGTH(username) >= 3')
    
    // Create the table - table name is already in the UserTable class
    ->createTableFromObject(new UserTable());

// Add a composite unique constraint
$generator->makeColumnsUniqueTogether(
    'user_addresses', 
    ['user_id', 'address_type']
);

// Update table when model changes
$generator = new TableGenerator();
$generator->updateTable(new UserTable());  // Table name comes from the UserTable class

// Safely remove a specific column
$generator->removeColumn('users', 'temporary_field');

// Modern image processing in one line
$image = new ImageHelper($uploadedFile)->convertToWebP(80);

// Validation in one line
if (!$request->definePostSchema(['email' => 'email', 'name' => 'string', '?bio' => 'string'])) {
    return $request->returnResponse();
}

// Type-safe database queries
$users = QueryBuilder::select('id', 'name')
    ->from('users')
    ->whereLike('name', "%$searchTerm%")
    ->orderBy('created_at', 'DESC')
    ->limit(10)
    ->run();
    
// Object mapping with consistent naming
$user = $request->mapPostToObject(new User(), ['username', 'email', 'first_name', 'last_name']);

// Clean, structured API responses
return (new JsonResponse())->success($data)->show();
bash
# For Apache/Nginx
php vendor/gemvc/library/bin/init.php apache

# For OpenSwoole
php vendor/gemvc/library/bin/init.php swoole