MVC like Laravel

Created At
2023-10-09

Model–view–controller (MVC) is a software design pattern commonly used for developing user interfaces that divides the related program logic into three interconnected elements.

This is done to separate internal representations of information from the ways information is presented to and accepted from the user.

Traditionally used for desktop graphical user interfaces (GUIs), this pattern became popular for designing web applications.

Popular programming languages have MVC frameworks that facilitate the implementation of the pattern like (PHP / Laravel) and (C# / .Net)

read more in wikipedia

now let's introduce our tiny framwark smiley

at first you can check the source code at GitHub

this educational project pring us three main concepts

Routing

Router simply is a class its responsibility to map urls that clients vist in your beautiful site with controller actions but in elegant way this leads to give this urls its functionalty

Middleware

Middlewares are fucntions  lie between http client request and response that send from the server

Dependency Injection

This technique is very usfull specially when gets compined with design patterns like strategy design pattern .

Its main goal to make the object independent of its dependencies by taking it as arguments or prameters and make the object itself dosen't now anything about creating it

 

Our tiny framwark features

  • provids some basics of routing like http requet methods and map urls to its action , naming , route prams and url genaration
  • di container that peforme some features like autowiring , interface binding ,costructor and function injection

Examples:

$router->get('/' ,function (\Src\Http\Request $request){
    return $request->uri() .  ' home page';
});

// name space works when callback is string ;
$router->group(['prefix'=> 'users' ,'as'=> 'users' ,'namespace'=> 'App\Controllers'],function (Router $router){
    $router->get('/',[UserController::class,'index'])->name('index');
    $router->post('/',[UserController::class,'store'])->name('store');
    $router->get('/create',[UserController::class,'create'])->name('create')
        ->middleware('working');
    // custom pram name is only string in slug format
    $router->get('/{name:[A-Za-z_-]}','UserController@show')->name('show');
    $router->put('/{id}',[UserController::class,'update'])->name('update');
    $router->delete('/{id}',[UserController::class,'destroy'])->name('destroy');
    $router->get('/{id}/edit',[UserController::class,'edit'])->name('edit');
});

in this code we use different http request methods get, post ,delete ,etc...

then passed actions as controller or string and give the urls names and prams({id},{name}) to make it dynamic but we can also specify the type of prams buy using regex in case of name pram
we need it text

class UserController
{
    public function create()
    {
        return Router::getByNameWithBinding('users.show',['id'=>1]);
    }
}

in this example we genarate url of route "users.show" with pram id equal 1
 

class UserController
{
    public function __construct(private readonly UserService $service){}
    
    
     public function index()
    {
        return $this->service->index();
    }
}

class UserService
{
    public function __construct(private readonly Request $request)
    {}
    public function index(): string
    {
        return $this->request::method();
    }
}

 

in this code when we make new instance of "UserController" class new inject a argument with type "UserService" and UserService itselef actuialy gets its own argument with type "Request"  this called autowiring