webfiori / http
Basic library that can help in creating RESTful APIs using PHP.
Fund package maintenance!
paypal.me/IbrahimBinAlshikh
Installs: 42 940
Dependents: 3
Suggesters: 0
Security: 0
Stars: 6
Watchers: 2
Forks: 0
Open Issues: 1
Requires
- php: >=7.0
- ext-json: *
- ext-mbstring: *
- webfiori/jsonx: 4.0.x
Requires (Dev)
- phpunit/phpunit: ^10.0
- dev-master
- dev-main
- 4.0.0
- 3.6.1
- 3.6.0
- 3.5.1
- 3.5.0
- 3.4.1
- 3.4.0
- v3.3.15
- v3.3.14
- v3.3.13
- v3.3.12
- v3.3.11
- v3.3.10
- v3.3.9
- v3.3.8
- v3.3.7
- v3.3.6
- v3.3.5
- v3.3.4
- v3.3.3
- v3.3.2
- v3.3.1
- v3.3.0
- v3.2.20
- v3.2.19
- v3.2.18
- v3.2.17
- v3.2.16
- v3.2.15
- v3.2.14
- v3.2.13
- v3.2.12
- v3.2.11
- v3.2.10
- v3.2.9
- v3.2.8
- v3.2.7
- v3.2.6
- v3.2.5
- v3.2.4
- v3.2.3
- v3.2.2
- v3.2.1
- v3.2.0
- v3.1.1
- v3.1.0
- v3.0.7
- v3.0.6
- v3.0.5
- v3.0.4
- v3.0.3
- v3.0.2
- v3.0.1
- v3.0.0
- v2.x-dev
- v2.0.2
- v2.0.1
- v2.0.0
- v1.5.1
- v1.5.0
- v1.4.9
- v1.4.8
- v1.4.7
- v1.4.6
- v1.4.5
- dev-release-please--branches--main
- dev-dev
- dev-release-please--branches--master
- dev-refactoring
- dev-feat-add-test-headers
- dev-fix-get-uri
- dev-cache
- dev-updated-json-lib
- dev-rename-to-http
- dev-abstraction
- dev-json-support
This package is auto-updated.
Last update: 2025-08-06 20:35:03 UTC
README
A powerful and flexible PHP library for creating RESTful web APIs with built-in input filtering, data validation, and comprehensive HTTP utilities. The library provides a clean, object-oriented approach to building web services with automatic parameter validation, authentication support, and JSON response handling.
Table of Contents
- Supported PHP Versions
- Key Features
- Installation
- Quick Start
- Core Concepts
- Creating Web Services
- Parameter Management
- Authentication & Authorization
- Request & Response Handling
- Advanced Features
- Testing
- Examples
- API Documentation
Supported PHP Versions
Build Status |
---|
Key Features
- RESTful API Development: Full support for creating REST services with JSON request/response handling
- Automatic Input Validation: Built-in parameter validation with support for multiple data types
- Custom Filtering: Ability to create user-defined input filters and validation rules
- Authentication Support: Built-in support for various authentication schemes (Basic, Bearer, etc.)
- HTTP Method Support: Support for all standard HTTP methods (GET, POST, PUT, DELETE, etc.)
- Content Type Handling: Support for
application/json
,application/x-www-form-urlencoded
, andmultipart/form-data
- Object Mapping: Automatic mapping of request parameters to PHP objects
- Comprehensive Testing: Built-in testing utilities with
APITestCase
class - Error Handling: Structured error responses with appropriate HTTP status codes
- Stream Support: Custom input/output stream handling for advanced use cases
Installation
Using Composer (Recommended)
composer require webfiori/http
Manual Installation
Download the latest release from GitHub Releases and include the autoloader:
require_once 'path/to/webfiori-http/vendor/autoload.php';
Quick Start
Here's a simple example to get you started:
<?php require_once 'vendor/autoload.php'; use WebFiori\Http\AbstractWebService; use WebFiori\Http\WebServicesManager; use WebFiori\Http\RequestMethod; use WebFiori\Http\ParamType; use WebFiori\Http\ParamOption; // Create a simple web service class HelloService extends AbstractWebService { public function __construct() { parent::__construct('hello'); $this->setRequestMethods([RequestMethod::GET]); $this->addParameters([ 'name' => [ ParamOption::TYPE => ParamType::STRING, ParamOption::OPTIONAL => true ] ]); } public function isAuthorized() { // No authentication required return true; } public function processRequest() { $name = $this->getParamVal('name'); if ($name !== null) { $this->sendResponse("Hello, $name!"); } else { $this->sendResponse("Hello, World!"); } } } // Set up the services manager $manager = new WebServicesManager(); $manager->addService(new HelloService()); $manager->process();
Core Concepts
Terminology
Term | Definition |
---|---|
Web Service | A single endpoint that implements a REST service, represented by AbstractWebService |
Services Manager | An entity that manages multiple web services, represented by WebServicesManager |
Request Parameter | A way to pass values from client to server, represented by RequestParameter |
API Filter | A component that validates and sanitizes request parameters |
Architecture Overview
The library follows a service-oriented architecture:
- AbstractWebService: Base class for all web services
- WebServicesManager: Manages multiple services and handles request routing
- RequestParameter: Defines and validates individual parameters
- APIFilter: Handles parameter filtering and validation
- Request/Response: Utilities for handling HTTP requests and responses
Creating Web Services
Basic Service Structure
Every web service must extend AbstractWebService
and implement the processRequest()
method:
<?php use WebFiori\Http\AbstractWebService; use WebFiori\Http\RequestMethod; class MyService extends AbstractWebService { public function __construct() { parent::__construct('my-service'); $this->setRequestMethods([RequestMethod::GET, RequestMethod::POST]); $this->setDescription('A sample web service'); } public function isAuthorized() { // Implement authorization logic return true; } public function processRequest() { // Implement service logic $this->sendResponse('Service executed successfully'); } }
Service Configuration
Setting Request Methods
// Single method $this->addRequestMethod(RequestMethod::POST); // Multiple methods $this->setRequestMethods([ RequestMethod::GET, RequestMethod::POST, RequestMethod::PUT ]);
Service Metadata
$this->setDescription('Creates a new user profile'); $this->setSince('1.2.0'); $this->addResponseDescription('Returns user profile data on success'); $this->addResponseDescription('Returns error message on failure');
Parameter Management
Parameter Types
The library supports various parameter types through ParamType
:
ParamType::STRING // String values ParamType::INT // Integer values ParamType::DOUBLE // Float/double values ParamType::BOOL // Boolean values ParamType::EMAIL // Email addresses (validated) ParamType::URL // URLs (validated) ParamType::ARR // Arrays ParamType::JSON_OBJ // JSON objects
Adding Parameters
Simple Parameter Addition
use WebFiori\Http\RequestParameter; $param = new RequestParameter('username', ParamType::STRING); $this->addParameter($param);
Batch Parameter Addition
$this->addParameters([ 'username' => [ ParamOption::TYPE => ParamType::STRING, ParamOption::OPTIONAL => false ], 'age' => [ ParamOption::TYPE => ParamType::INT, ParamOption::OPTIONAL => true, ParamOption::MIN => 18, ParamOption::MAX => 120, ParamOption::DEFAULT => 25 ], 'email' => [ ParamOption::TYPE => ParamType::EMAIL, ParamOption::OPTIONAL => false ] ]);
Parameter Options
Available options through ParamOption
:
ParamOption::TYPE // Parameter data type ParamOption::OPTIONAL // Whether parameter is optional ParamOption::DEFAULT // Default value for optional parameters ParamOption::MIN // Minimum value (numeric types) ParamOption::MAX // Maximum value (numeric types) ParamOption::MIN_LENGTH // Minimum length (string types) ParamOption::MAX_LENGTH // Maximum length (string types) ParamOption::EMPTY // Allow empty strings ParamOption::FILTER // Custom filter function ParamOption::DESCRIPTION // Parameter description
Custom Validation
$this->addParameters([ 'password' => [ ParamOption::TYPE => ParamType::STRING, ParamOption::MIN_LENGTH => 8, ParamOption::FILTER => function($original, $basic) { // Custom validation logic if (strlen($basic) < 8) { return APIFilter::INVALID; } // Additional password strength checks return $basic; } ] ]);
Retrieving Parameter Values
public function processRequest() { $username = $this->getParamVal('username'); $age = $this->getParamVal('age'); $email = $this->getParamVal('email'); // Get all inputs as array $allInputs = $this->getInputs(); }
Authentication & Authorization
Basic Authentication Implementation
public function isAuthorized() { $authHeader = $this->getAuthHeader(); if ($authHeader === null) { return false; } $scheme = $authHeader->getScheme(); $credentials = $authHeader->getCredentials(); if ($scheme === 'basic') { // Decode base64 credentials $decoded = base64_decode($credentials); list($username, $password) = explode(':', $decoded); // Validate credentials return $this->validateUser($username, $password); } return false; }
Bearer Token Authentication
public function isAuthorized() { $authHeader = $this->getAuthHeader(); if ($authHeader === null) { return false; } if ($authHeader->getScheme() === 'bearer') { $token = $authHeader->getCredentials(); return $this->validateToken($token); } return false; }
Skipping Authentication
public function __construct() { parent::__construct('public-service'); $this->setIsAuthRequired(false); // Skip authentication }
Custom Error Messages
use WebFiori\Http\ResponseMessage; public function isAuthorized() { ResponseMessage::set('401', 'Custom unauthorized message'); // Your authorization logic return false; }
Request & Response Handling
Sending JSON Responses
// Simple message response $this->sendResponse('Operation completed successfully'); // Response with type and status code $this->sendResponse('User created', 'success', 201); // Response with additional data $userData = ['id' => 123, 'name' => 'John Doe']; $this->sendResponse('User retrieved', 'success', 200, $userData);
Custom Content Type Responses
// Send XML response $xmlData = '<user><id>123</id><name>John Doe</name></user>'; $this->send('application/xml', $xmlData, 200); // Send plain text $this->send('text/plain', 'Hello, World!', 200); // Send file download $this->send('application/octet-stream', $fileContent, 200);
Handling Different Request Methods
public function processRequest() { $method = $this->getManager()->getRequestMethod(); switch ($method) { case RequestMethod::GET: $this->handleGet(); break; case RequestMethod::POST: $this->handlePost(); break; case RequestMethod::PUT: $this->handlePut(); break; case RequestMethod::DELETE: $this->handleDelete(); break; } }
JSON Request Handling
The library automatically handles JSON requests when Content-Type: application/json
:
public function processRequest() { $inputs = $this->getInputs(); if ($inputs instanceof \WebFiori\Json\Json) { // Handle JSON input $name = $inputs->get('name'); $email = $inputs->get('email'); } else { // Handle form data $name = $inputs['name'] ?? null; $email = $inputs['email'] ?? null; } }
Advanced Features
Object Mapping
Automatically map request parameters to PHP objects:
class User { private $name; private $email; private $age; public function setName($name) { $this->name = $name; } public function setEmail($email) { $this->email = $email; } public function setAge($age) { $this->age = $age; } // Getters... } public function processRequest() { // Automatic mapping $user = $this->getObject(User::class); // Custom setter mapping $user = $this->getObject(User::class, [ 'full-name' => 'setName', 'email-address' => 'setEmail' ]); }
Services Manager Configuration
$manager = new WebServicesManager(); // Set API version and description $manager->setVersion('2.1.0'); $manager->setDescription('User Management API'); // Add multiple services $manager->addService(new CreateUserService()); $manager->addService(new GetUserService()); $manager->addService(new UpdateUserService()); $manager->addService(new DeleteUserService()); // Custom input/output streams $manager->setInputStream('php://input'); $manager->setOutputStream(fopen('api-log.txt', 'a')); // Process requests $manager->process();
Error Handling
public function processRequest() { try { // Service logic $result = $this->performOperation(); $this->sendResponse('Success', 'success', 200, $result); } catch (ValidationException $e) { $this->sendResponse($e->getMessage(), 'error', 400); } catch (AuthenticationException $e) { $this->sendResponse('Unauthorized', 'error', 401); } catch (Exception $e) { $this->sendResponse('Internal server error', 'error', 500); } }
Custom Filters
use WebFiori\Http\APIFilter; $customFilter = function($original, $filtered) { // Custom validation logic if (strlen($filtered) < 3) { return APIFilter::INVALID; } // Additional processing return strtoupper($filtered); }; $this->addParameters([ 'code' => [ ParamOption::TYPE => ParamType::STRING, ParamOption::FILTER => $customFilter ] ]);
Testing
Using APITestCase
<?php use WebFiori\Http\APITestCase; class MyServiceTest extends APITestCase { public function testGetRequest() { $manager = new WebServicesManager(); $manager->addService(new MyService()); $response = $this->getRequest($manager, 'my-service', [ 'param1' => 'value1', 'param2' => 'value2' ]); $this->assertJson($response); $this->assertContains('success', $response); } public function testPostRequest() { $manager = new WebServicesManager(); $manager->addService(new MyService()); $response = $this->postRequest($manager, 'my-service', [ 'name' => 'John Doe', 'email' => 'john@example.com' ]); $this->assertJson($response); } }
Manual Testing
// Set up test environment $_GET['service'] = 'my-service'; $_GET['param1'] = 'test-value'; $_SERVER['REQUEST_METHOD'] = 'GET'; $manager = new WebServicesManager(); $manager->addService(new MyService()); $manager->process();
Examples
Complete CRUD Service Example
<?php class UserService extends AbstractWebService { public function __construct() { parent::__construct('user'); $this->setRequestMethods([ RequestMethod::GET, RequestMethod::POST, RequestMethod::PUT, RequestMethod::DELETE ]); $this->addParameters([ 'id' => [ ParamOption::TYPE => ParamType::INT, ParamOption::OPTIONAL => true ], 'name' => [ ParamOption::TYPE => ParamType::STRING, ParamOption::OPTIONAL => true, ParamOption::MIN_LENGTH => 2 ], 'email' => [ ParamOption::TYPE => ParamType::EMAIL, ParamOption::OPTIONAL => true ] ]); } public function isAuthorized() { return true; // Implement your auth logic } public function processRequest() { $method = $this->getManager()->getRequestMethod(); switch ($method) { case RequestMethod::GET: $this->getUser(); break; case RequestMethod::POST: $this->createUser(); break; case RequestMethod::PUT: $this->updateUser(); break; case RequestMethod::DELETE: $this->deleteUser(); break; } } private function getUser() { $id = $this->getParamVal('id'); if ($id) { // Get specific user $user = $this->findUserById($id); $this->sendResponse('User found', 'success', 200, $user); } else { // Get all users $users = $this->getAllUsers(); $this->sendResponse('Users retrieved', 'success', 200, $users); } } private function createUser() { $name = $this->getParamVal('name'); $email = $this->getParamVal('email'); $user = $this->createNewUser($name, $email); $this->sendResponse('User created', 'success', 201, $user); } private function updateUser() { $id = $this->getParamVal('id'); $name = $this->getParamVal('name'); $email = $this->getParamVal('email'); $user = $this->updateExistingUser($id, $name, $email); $this->sendResponse('User updated', 'success', 200, $user); } private function deleteUser() { $id = $this->getParamVal('id'); $this->removeUser($id); $this->sendResponse('User deleted', 'success', 200); } }
File Upload Service
<?php class FileUploadService extends AbstractWebService { public function __construct() { parent::__construct('upload'); $this->setRequestMethods([RequestMethod::POST]); $this->addParameters([ 'file' => [ ParamOption::TYPE => ParamType::STRING, ParamOption::OPTIONAL => false ], 'description' => [ ParamOption::TYPE => ParamType::STRING, ParamOption::OPTIONAL => true ] ]); } public function isAuthorized() { return true; } public function processRequest() { if (isset($_FILES['file'])) { $file = $_FILES['file']; if ($file['error'] === UPLOAD_ERR_OK) { $uploadPath = 'uploads/' . basename($file['name']); if (move_uploaded_file($file['tmp_name'], $uploadPath)) { $this->sendResponse('File uploaded successfully', 'success', 200, [ 'filename' => $file['name'], 'size' => $file['size'], 'path' => $uploadPath ]); } else { $this->sendResponse('Failed to move uploaded file', 'error', 500); } } else { $this->sendResponse('File upload error', 'error', 400); } } else { $this->sendResponse('No file uploaded', 'error', 400); } } }
For more examples, check the examples directory in this repository.
API Documentation
This library is part of the WebFiori Framework. For complete API documentation, visit: https://webfiori.com/docs/webfiori/http
Key Classes Documentation
AbstractWebService
- Base class for web servicesWebServicesManager
- Services managementRequestParameter
- Parameter definition and validationAPIFilter
- Input filtering and validationRequest
- HTTP request utilitiesResponse
- HTTP response utilities
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- Issues: GitHub Issues
- Documentation: WebFiori Docs
- Examples: Examples Directory
Changelog
See CHANGELOG.md for a list of changes and version history.