Skip to content

This is a light weight route system library for php 8.1 and higher versions .

License

Notifications You must be signed in to change notification settings

zanko-khaledi/php-simple-router

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

php-simple-router

this light weight router library can be useful for small php web projects or building you'r api.

installation

$ composer require zanko-khaledi/php-simple-router

Usage

You can use this router like below

 <?php

 use ZankoKhaledi\PhpSimpleRouter\Request;
 use ZankoKhaledi\PhpSimpleRouter\Router;

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

 Router::get('/',function (Request $request){
     echo "Hello World";
 });

 Router::get('/foo',function (Request $request){
     echo "foo route";
 });

 Router::executeRoutes();

Use Controller instead of callback functions

 <?php

  use App\Controllers\FooController; 
  use ZankoKhaledi\PhpSimpleRouter\Router;

  require __DIR__ . "/vendor/autoload.php";
  
  
  Router::get('/foo/create',[FooController::class,'create']);
  
  Router::post('/foo',[FooController::class,'store']);

  Router::executeRoutes();

However you would be able to use dynamic route parameters

 <?php
 
 use ZankoKhaledi\PhpSimpleRouter\Request; 
 use ZankoKhaledi\PhpSimpleRouter\Router;

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

 Router::get('/bar/{id}',function (Request $request){
    echo $request->params()->id;
 });
 
 Router::get('/foo/{file}',function (Request $request){
    echo $request->params()->file;
 })->where('/foo\/[a-z]+/');

 Router::executeRoutes();

Router Collection

Add router collection for modular routing

<?php
 
 use ZankoKhaledi\PhpSimpleRouter\RouterCollection;

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

 
 RouterCollection::executeRoutesFrom('./Modules/*/routes/*.php');
  

Notice

If you use RouterCollection class for load your route files , you have to avoid call Router::executeRoutes() in your route files because this method calling once you invoke executeRoutesFrom() method from RouterCollection so just do like this :
  <?php
  
   // Modules/Product/routes/product.php
   
   use ZankoKhaledi\PhpSimpleRouter\Router;
   use ZankoKhaledi\PhpSimpleRouter\Request;
   
   Router::get('/products',function (Request $request){
      // your code
   });
    

Request methods

You can use only this request methods to handle you're api

   GET,POST,PUT,PATCH,DELETE

Middleware

Create a class for example AuthMiddleware that implements IMiddleware contract

<?php

 use ZankoKhaledi\PhpSimpleRouter\Interfaces\IMiddleware;
 use ZankoKhaledi\PhpSimpleRouter\Interfaces\IRequest;
  
 class AuthMiddleware implements IMiddleware
 {
   public function handle(IRequest $request,Callable $next)
   {
     if(!isset($_SESSION['admin']) && $_SESSION['admin'] !== 'zanko'){
           header("Location:/");
           exit();
     }
     $next($request);
   }
 }

After middleware has been created you should register it on you're router

<?php

  use App\Middlewares\AuthMiddleware;
  use ZankoKhaledi\PhpSimpleRouter\Router;
  use ZankoKhaledi\PhpSimpleRouter\Request;

  require __DIR__ . "/vendor/autoload.php";
  
  Router::get('/foo',function (Request $request){
     // your code
  })->middleware([AuthMiddleware::class]); 

  Router::executeRoutes();

Group

you can use group route binding

<?php
  use ZankoKhaledi\PhpSimpleRouter\Request; 
  use ZankoKhaledi\PhpSimpleRouter\Router;
  use ZankoKhaledi\PhpSimpleRouter\Interfaces\IRoute;

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

  Router::group(['prefix' => '/foo'],function (Request $request){
     Router::get('/bar',function (Request $request){
        // your code
     });
  });

  Router::executeRoutes();

Also you would be able to bind middlewares to group method

<?php
  use ZankoKhaledi\PhpSimpleRouter\Request; 
  use ZankoKhaledi\PhpSimpleRouter\Router;
  use App\Middelwares\AuthMiddleware;
  use App\Controllers\FooController;

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

 
  
  Router::group(['prefix' => '/bar','middleware' => [AuthMiddleware::class]],function (){
  
      Router::get('/foo/{id}',function (Request $request){
         echo $request->params()->id;
      });
      
      Router::post('/foo',[FooController::class,'store']);
      
  }); 

  Router::executeRoutes();

You can also use subdomains in group method like block code below

  use ZankoKhaledi\PhpSimpleRouter\Request; 
  use ZankoKhaledi\PhpSimpleRouter\Router;
  use App\Middelwares\AuthMiddleware;

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


  Router::group([
  'domain' => 'example.local'
  ,'prefix' => '/bar'
  ,'middleware' => [AuthMiddleware::class]]
  ,function (){
     // code  
  }); 

  Router::executeRoutes();

By default you're host name is localhost you would be able to change it in .env file on root of you're project for example


HOSTNAME = mysite.local

after setting HOSTNAME variable in .env file you must to add this line of code inside of index.php file in root of your project or in public directory

  use ZankoKhaledi\PhpSimpleRouter\Request; 
  use ZankoKhaledi\PhpSimpleRouter\Router;
  use ZankoKhaledi\PhpSimpleRouter\RouterCollection;
  use App\Middelwares\AuthMiddleware;

  require __DIR__ . "/vendor/autoload.php";
  
  Router::loadConfigs(__DIR__); // this method called for loading .env variables
  
  Router::group([
  'domain' => 'subdomain.mysite.local'
  ,'prefix' => '/bar'
  ,'middleware' => [AuthMiddleware::class]]
  ,function (){
     // code  
  }); 

  Router::executeRoutes();

Testing

<?php
     
     declare(strict_types=1);
     
     use PHPUnit\Framework\TestCase;
     use ZankoKhaledi\PhpSimpleRouter\Router;
     
     class Test extends TestCase
     {
     
         protected string $baseUri = 'http://localhost:8000';
     
         public function test_get_route()
         {
             $request = Router::assertRequest($this->baseUri);
             $response = $request->assertGet('/foo',[]);
     
             $this->assertEquals(200,$response->status());
             $this->assertJson($response->json());
             $this->assertSame(json_encode([
                 'name' => 'Zanko'
             ]),$response->body());
         }
     
     
         public function test_foo_post_route()
         {
             $request = Router::assertRequest($this->baseUri);
             $response = $request->assertPost('/foo',[
                'form_params' => [
                    'name' => 'Teddy'
                ]
             ]);
     
             $this->assertEquals(201,$response->status());
             $this->assertJson($response->json());
             $this->assertSame(json_encode([
                 'name' => 'Foo'
             ]),$response->json());
         }
     }   
    

You can test you're api like code block above. some test api :

  <?php
    
    use ZankoKhaledi\PhpSimpleRouter\Router;
    
    $baseUri = 'http://localhost:8000';
    $request = Router::assertRequest($baseUri) // config base uri for sending requests to server 
    
    $request->assertGet($route,[]); // route like /foo
 
    $request->assertPost($route,[]);

    $request->assertPut($route,[]);

    $request->assertPatch($route,[]);

    $request->assertDelete($route,[]);

if you familiar to PHPUnit test framework and Guzzle/Http library you could test you're api without Router test api by default.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT