PHP Classes

PHP AJAX Response Router: Handle HTTP AJAX requests using router classes

Recommend this page to a friend!
  Info   Documentation   View files Files   Install with Composer Install with Composer   Download Download   Reputation   Support forum   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2024-12-03 (10 days ago) RSS 2.0 feedStarStarStarStar 70%Total: 145 This week: 2All time: 9,144 This week: 29Up
Version License PHP version Categories
ajax-router 1.0.7MIT/X Consortium ...5.6HTTP, PHP 5, Design Patterns, AJAX, PSR
Description 

Author

This package can handle HTTP AJAX requests using router classes.

It can process HTTP requests using classes that create request objects compliant with the PSR 7 specification.

The package can process the request message objects using a router class configured to handle requests of certain types and specific request parameter values by calling given callback functions or class methods.

It also provides a response class that is compliant with PSR 7 specification.

Callback functions can create response objects that the package can process to output the response headers and body data to the current HTTP request.

The package can also catch exceptions and route the request handling to a given callback function.

Innovation Award
PHP Programming Innovation award winner
February 2022
Winner


Prize: One official elePHPant Plush Mascott
PSR-7 is a PHP standard recommendation for creating PHP classes that can encapsulate the details of an HTTP request and an HTTP response.

This package implements the PSR-7 recommendation to simplify the processing of HTTP requests of AJAX and other types of PHP Web applications.

Application developers only need to specify callback functions or class methods ready to process PSR-7 compliant requests and response objects to implement their PHP applications.

Manuel Lemos
Picture of Shakir El Amrani
  Performance   Level  
Name: Shakir El Amrani <contact>
Classes: 3 packages by
Country: Morocco Morocco
Innovation award
Innovation award
Nominee: 2x

Winner: 1x

Documentation

packagist tests License

Getting Started

composer require amranich/ajax-router

You can copy/paste this code snippet for a quick start.

We're using Guzzle PSR-7 interface implementation here, but you can use any other library you like as long as it implements the same interface.

<?php

require __DIR__ . '/vendor/autoload.php';

use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use AmraniCh\AjaxRouter\Route;
use AmraniCh\AjaxRouter\Router;
use AmraniCh\AjaxRouter\Dispatcher;
use GuzzleHttp\Psr7\ServerRequest;
use Lazzard\Psr7ResponseSender\Sender;

try {
    $request = ServerRequest::fromGlobals();
    
    // the 'X-requested-with' header is commonly used to inform the server that a request 
    // is sent via the XMLHttpRequest object on the client-side, a lot of JavaScript libraries 
    // like jQuery already send this header automatically, this check can add a small security
    // layer to your app because HTTP headers can be spoofed very easily, so don't count on
    // only that check.
    if (!$request->hasHeader('X-requested-with') 
        || strtolower($request->getHeader('X-requested-with')[0]) !== 'XMLHttpRequest') {
        throw new BadRequestException("Accept only AJAX requests.");
    }
    
    // to organize your project, you can put your routes in a separate file like in an array
    // and require it in the second parameter of the router constructor.  
    $router = new Router($request, 'route', [
    
        // ?route=getPost&id=1005
        Route::get('getPost', function ($params) {
        
            // PSR7 responses are a little annoying to work with, you always have extra HTTP layers 
            // in your app that extend the base PSR7 response class, think of a class like JsonResponse, 
            // and in the constructor add the content-type header and pass it to the parent class.
            $response = new Response;

            $response->getBody()->write(json_encode([
                'id' => $params['id'],
                'title' => 'Best Places to Visit in Marrakech',
                'description' => 'Example of post description',
                'created_at' => '2022-02-27 03:00:05'
            ]));

            return $response->withHeader('Content-type', 'application/json');
        }),
    ]);

    $dispatcher = new Dispatcher($router);
    $dispatcher->dispatch();

} catch (Exception $ex) {
    $response = new Response(
        $ex->getCode() ?: 500,
        ['Content-type' => 'application/json'],
        json_encode(['message' => $ex->getMessage()])
    );

    $sender = new Sender;
    $sender($response);
}

Usage Tips

Route to controller/class method

If you like to put the business logic in a separate class or in a controller, you can route your requests to them like this :

Route::get('getPost', [PostController::class, 'getPost']);

Or :

Route::get('getPost', 'PostController@getPost');

// register the controller class or instance in the router
$router->registerControllers([
    PostController::class,
]);

If the controller/class has some dependencies that must be passed within the constructor, you can still instantiate the controller on yourself :

$router->registerControllers([
    new PostController($dependencyOne, $dependencyTwo)
]);

Catch route actions exceptions

*I want to catch exceptions that only occurs from my routes actions, and not those thrown by the library or somewhere else, how I can do that ?*

Answer :

$dispatcher->onException(function (\Exception $ex) {
    // $ex exception thrown by a route action
});

Get current route

You can access the current route object using the static method getCurrentRoute of the Route class.

$route = Router::getCurrentRoute();
$route->getName();
$route->getMethods();
$route->getValue();

Background

The idea of the library came to my mind a long time ago when I was mostly developing web applications using just plain PHP, some of these applications were performing a lot of AJAX requests into a single PHP file, that file can have a hundred lines of code that process these requests depending on a function/method name that sent along with the request, so I started to think of what I can do to improve the way that these requests are handled, and improve the code readability and maintainability.

Prizes

This package wins the PHP Innovation Award (February 2022) Issued by phpclasses.org

? Prize : One elePHPant mascot. https://www.php.net/elephpant.php

? Certificate : https://amranich.dev/certs/phpclasses-february-2022-innovation-award.pdf

They support this project

<img width="150px" src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_square.png"/>


  Files folder image Files (27)  
File Role Description
Files folder image.github (1 directory)
Files folder imagesrc (3 files, 3 directories)
Files folder imagetests (1 directory)
Accessible without login Plain text file CHANGELOG.md Data Auxiliary data
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file phpunit.xml Data Auxiliary data
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (27)  /  .github  
File Role Description
Files folder imageworkflows (1 file)

  Files folder image Files (27)  /  .github  /  workflows  
File Role Description
  Accessible without login Plain text file tests.yml Data Auxiliary data

  Files folder image Files (27)  /  src  
File Role Description
Files folder imageException (10 files)
Files folder imagePsr7 (1 file)
Files folder imageRouteResolver (2 files)
  Plain text file Dispatcher.php Class Class source
  Plain text file Route.php Class Class source
  Plain text file Router.php Class Class source

  Files folder image Files (27)  /  src  /  Exception  
File Role Description
  Plain text file AjaxRouterException.php Class Class source
  Plain text file BadRequestException.php Class Class source
  Plain text file HttpExceptionTrait.php Class Class source
  Plain text file InvalidArgumentException.php Class Class source
  Plain text file LogicException.php Class Class source
  Plain text file MethodNotAllowedException.php Class Class source
  Plain text file RouteNotFoundException.php Class Class source
  Plain text file RoutesFileException.php Class Class source
  Plain text file RuntimeException.php Class Class source
  Plain text file UnexpectedValueException.php Class Class source

  Files folder image Files (27)  /  src  /  Psr7  
File Role Description
  Plain text file Psr7RequestAdapter.php Class Class source

  Files folder image Files (27)  /  src  /  RouteResolver  
File Role Description
  Plain text file ControllerMethod.php Class Class source
  Plain text file RouteResolver.php Class Class source

  Files folder image Files (27)  /  tests  
File Role Description
Files folder imageUnit (3 files, 2 directories)

  Files folder image Files (27)  /  tests  /  Unit  
File Role Description
Files folder imagePsr7 (1 file)
Files folder imageRouteResolver (1 file)
  Plain text file DispatcherTest.php Class Class source
  Plain text file RouterTest.php Class Class source
  Plain text file RouteTest.php Class Class source

  Files folder image Files (27)  /  tests  /  Unit  /  Psr7  
File Role Description
  Plain text file Psr7RequestAdapterTest.php Class Class source

  Files folder image Files (27)  /  tests  /  Unit  /  RouteResolver  
File Role Description
  Plain text file RouteResolverTest.php Class Class source

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Install with Composer Install with Composer
 Version Control Unique User Downloads Download Rankings  
 100%
Total:145
This week:2
All time:9,144
This week:29Up
User Ratings User Comments (1)
 All time
Utility:100%StarStarStarStarStarStar
Consistency:100%StarStarStarStarStarStar
Documentation:100%StarStarStarStarStarStar
Examples:-
Tests:-
Videos:-
Overall:70%StarStarStarStar
Rank:308
 
Thats a very good class ;-)
2 years ago (José Filipe Lopes Santos)
70%StarStarStarStar