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/ */
// 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);
}
}
// 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
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.