Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Routing Laravel

Routing Laravel

Let's find how Route:: works and where we can reuse it for our own technical challenges.

Talk was given at Laracon Online 2021, march 17th.

Bobby Bouwmann

March 17, 2021
Tweet

More Decks by Bobby Bouwmann

Other Decks in Programming

Transcript

  1. Laravel Fashionista • Laravel Evangelist @ Enrise • Top Contributor

    @ Laracasts • Writer of Laravel Secrets • Partner @ PingPing.io @bobbybouwmann
  2. Enrise We are the new standard in organising No management,

    no board, but professionals who take control
  3. Better order that pizza now! • Laravel basic routing •

    Routing cycle • Route model binding explained • Another use case for the router • Best practices Today’s menu Photo by Natasha Filippovskaya from Pexels
  4. <?ph p use Illuminate\Support\Facades\Route ; / * |------------------------------------------------------------------------- - |

    Web Route s |------------------------------------------------------------------------- - | | Here is where you can register web routes for your application. Thes e | routes are loaded by the RouteServiceProvider within a group whic h | contains the "web" middleware group. Now create something great ! | * / Route::get('/', function () { return view('welcome') ; });
  5. // Basic Controller Route::get('/users/{user}', [UsersController::class, ‘show'] ) ->name('users.show') ; //

    Invokable Controlle r Route::get('/users/{user}', EditUser::class ) ->name(‘users.edit') ; // Callbac k Route::get('/', function () { return view('welcome') ; });
  6. Route::get('posts', [PostsController::class, ‘index'])->name('posts.index') ; Route::get('posts/create', [PostsController::class, ‘create'])->name('posts.create') ; Route::post('posts', [PostsController::class,

    ‘store'])->name('posts.store') ; Route::get('posts/{post}', [PostsController::class, ‘show'])->name('posts.show') ; Route::get('posts/{post}/edit', [PostsController::class, ‘edit'])->name('posts.edit') ; Route::put('posts/{post}', [PostsController::class, ‘update’])->name('posts.update') ; Route::patch('posts/{post}', [PostsController::class, ‘update'])->name('posts.update') ; Route::delete('posts/{post}', [PostsController::class, ‘destroy'])->name('posts.destroy');
  7. $ php artisan route:list +-----------+--------------------+----------------+-----------------------------------------------+------------+ | Method | URI |

    Name | Action | Middleware | +-----------+--------------------+----------------+-----------------------------------------------+------------+ | GET|HEAD | posts | posts.index | App\Http\Controllers\PostsController@index | web | | POST | posts | posts.store | App\Http\Controllers\PostsController@store | web | | GET|HEAD | posts/create | posts.create | App\Http\Controllers\PostsController@create | web | | GET|HEAD | posts/{post} | posts.show | App\Http\Controllers\PostsController@show | web | | PUT|PATCH | posts/{post} | posts.update | App\Http\Controllers\PostsController@update | web | | DELETE | posts/{post} | posts.destroy | App\Http\Controllers\PostsController@destroy | web | | GET|HEAD | posts/{post}/edit | posts.edit | App\Http\Controllers\PostsController@edit | web | +-----------+--------------------+----------------+-----------------------------------------------+------------+ $ php artisan route:list --compact +-----------+--------------------+-----------------------------------------------+ | Method | URI | Action | +-----------+--------------------+-----------------------------------------------+ | GET|HEAD | posts | App\Http\Controllers\PostsController@index | | POST | posts | App\Http\Controllers\PostsController@store | | GET|HEAD | posts/create | App\Http\Controllers\PostsController@create | | GET|HEAD | posts/{post} | App\Http\Controllers\PostsController@show | | PUT|PATCH | posts/{post} | App\Http\Controllers\PostsController@update | | DELETE | posts/{post} | App\Http\Controllers\PostsController@destroy | | GET|HEAD | posts/{post}/edit | App\Http\Controllers\PostsController@edit | +-----------+--------------------+-----------------------------------------------+
  8. Route::resource('posts', PostsController::class); $ php artisan route:list --compact +-----------+--------------------+-----------------------------------------------+ | Method

    | URI | Action | +-----------+--------------------+-----------------------------------------------+ | GET|HEAD | / | Closure | | GET|HEAD | posts | App\Http\Controllers\PostsController@index | | POST | posts | App\Http\Controllers\PostsController@store | | GET|HEAD | posts/create | App\Http\Controllers\PostsController@create | | GET|HEAD | posts/{post} | App\Http\Controllers\PostsController@show | | PUT|PATCH | posts/{post} | App\Http\Controllers\PostsController@update | | DELETE | posts/{post} | App\Http\Controllers\PostsController@destroy | | GET|HEAD | posts/{post}/edit | App\Http\Controllers\PostsController@edit | +-----------+--------------------+-----------------------------------------------+
  9. Route::resource('posts', PostsController::class)->middleware(‘auth')->names('blog'); Route::resource('posts', PostsController::class)->name('index', 'blog'); $ php artisan route:list +-----------+--------------------+----------------+-----------------------------------------------+------------+

    | Method | URI | Name | Action | Middleware | +-----------+--------------------+----------------+-----------------------------------------------+------------+ | GET|HEAD | posts | blog.index | App\Http\Controllers\PostsController@index | web, auth | | POST | posts | blog.store | App\Http\Controllers\PostsController@store | web, auth | | GET|HEAD | posts/create | blog.create | App\Http\Controllers\PostsController@create | web, auth | | GET|HEAD | posts/{post} | blog.show | App\Http\Controllers\PostsController@show | web, auth | | PUT|PATCH | posts/{post} | blog.update | App\Http\Controllers\PostsController@update | web, auth | +-----------+--------------------+----------------+-----------------------------------------------+------------+ $ php artisan route:list +-----------+--------------------+----------------+-----------------------------------------------+------------+ | Method | URI | Name | Action | Middleware | +-----------+--------------------+----------------+-----------------------------------------------+------------+ | GET|HEAD | posts | blog | App\Http\Controllers\PostsController@index | web | | POST | posts | posts.store | App\Http\Controllers\PostsController@store | web | | GET|HEAD | posts/create | posts.create | App\Http\Controllers\PostsController@create | web | | GET|HEAD | posts/{post} | posts.show | App\Http\Controllers\PostsController@show | web | | PUT|PATCH | posts/{post} | posts.update | App\Http\Controllers\PostsController@update | web | +-----------+--------------------+----------------+-----------------------------------------------+------------+
  10. Route::name('posts.index' ) ->prefix('posts' ) ->middleware('auth' ) ->domain('portal.example.com' ) ->get('list', [PostsController::class,

    'index']) ; Route::name('posts.update' ) ->prefix('posts' ) ->middleware('auth' ) ->domain('portal.example.com' ) ->patch('{post}', [PostsController::class, 'update']); $ php artisan route:list +--------------------+----------+-------------+--------------+---------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------------------+----------+-------------+--------------+---------------------------------------------+------------+ | portal.example.com | GET|HEAD | posts/list | posts.index | App\Http\Controllers\PostsController@index | web | | | | | | | auth | | portal.example.com | PATCH | posts/{post}| posts.update | App\Http\Controllers\PostsController@update | web | | | | | | | auth | +--------------------+----------+-------------+--------------+---------------------------------------------+------------+
  11. Route::name('posts.' ) ->prefix('posts' ) ->middleware('auth' ) ->domain('{vendor}.example.com' ) ->group(function ()

    { Route::get('list', [PostsController::class, 'index'])->name('list') ; Route::get('public', [PostsController::class, 'public'])->name('public') ; }) ; $ php artisan route:list +----------------------+----------+--------------------+-----------------+------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +----------------------+----------+--------------------+-----------------+------------------------------------------------+------------+ | {vendor}.example.com | GET|HEAD | posts/list | posts.list | App\Http\Controllers\PostsController@index | web | | | | | | | auth | | {vendor}.example.com | GET|HEAD | posts/published | posts.published | App\Http\Controllers\PostsController@published | web | | | | | | | auth | +----------------------+----------+--------------------+-----------------+------------------------------------------------+------------+
  12. Route::middleware('auth')->group(function () { Route::get('blog/{post}', [PostsController::class, 'show'])->name('posts.show') ; Route::middleware('throttle:10|60,1')->group(function () {

    Route::get('blog', [PostsController::class, 'index'])->name('posts.index') ; }) ; Route::middleware('verified')->group(function () { Route::get('posts/create', [PostsController::class, 'create'])->name('posts.index') ; Route::post('posts/store', [PostsController::class, 'store'])->name('posts.store') ; }) ; }); $ php artisan route:list --columns=method,name,action,middleware +----------+-------------+---------------------------------------------+------------------+ | Method | Name | Action | Middleware | +----------+-------------+---------------------------------------------+------------------+ | GET|HEAD | posts.index | App\Http\Controllers\PostsController@index | web | | | | | auth | | | | | throttle:10|60,1 | | GET|HEAD | posts.show | App\Http\Controllers\PostsController@show | web | | | | | auth | | GET|HEAD | posts.index | App\Http\Controllers\PostsController@create | web | | | | | auth | | | | | verified | | POST | posts.store | App\Http\Controllers\PostsController@store | web | | | | | auth | | | | | verified | +----------+-------------+---------------------------------------------+------------------+
  13. <?ph p namespace App\Providers ; use Illuminate\Cache\RateLimiting\Limit ; use Illuminate\Foundation\Support\Providers\RouteServiceProvider

    as ServiceProvider ; use Illuminate\Http\Request ; use Illuminate\Support\Facades\RateLimiter ; use Illuminate\Support\Facades\Route ; class RouteServiceProvider extends ServiceProvide r { /* * * The path to the "home" route for your application . * * This is used by Laravel authentication to redirect users after login . * * @var strin g * / public const HOME = '/home' ; /* * * The controller namespace for the application . * * When present, controller route declarations will automatically be prefixed with this namespace . * * @var string|nul l * / // protected $namespace = 'App\\Http\\Controllers' ;
  14. ; use Illuminate\Support\Facades\Route ; class RouteServiceProvider extends ServiceProvide r {

    /* * * The path to the "home" route for your application . * * This is used by Laravel authentication to redirect users after login . * * @var strin g * / public const HOME = '/home' ; /* * * The controller namespace for the application . * * When present, controller route declarations will automatically be prefixed with this namespace . * * @var string|nul l * / // protected $namespace = 'App\\Http\\Controllers' ; /* * * Define your route model bindings, pattern filters, etc . * * @return voi d * / public function boot( ) { $this->configureRateLimiting() ; protected $namespace = 'App\\Http\\Controllers'; Route::get('/users/{user}', 'UsersController@show');
  15. /* * * Define your route model bindings, pattern filters,

    etc . * * @return voi d * / public function boot( ) { $this->configureRateLimiting() ; $this->routes(function () { Route::prefix('api' ) ->middleware('api' ) ->namespace($this->namespace ) ->group(base_path('routes/api.php')) ; Route::middleware('web' ) ->namespace($this->namespace ) ->group(base_path('routes/web.php')) ; }) ; } /* * * Configure the rate limiters for the application . * * @return voi d * / protected function configureRateLimiting( ) { RateLimiter::for('api', function (Request $request) { return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip()) ; ;
  16. Route::match(['get', 'post'], 'login', function (Request $request) { / / })->name('login')

    ; Route::any('register', function (Request $request) { / / })->name('register'); $ php artisan route:list --columns=method,name,action,middleware +----------------------------------------+----------------+----------------+------------+ | Method | Name | Action | Middleware | +----------------------------------------+----------------+----------------+------------+ | GET|POST|HEAD | login | Closure | web | | GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS | register | Closure | web | +----------------------------------------+----------------+----------------+------------+
  17. Route::get('dashboard', DashboardController::class)->name('dashboard') ; // Redirect to a different URL, HTTP

    status code 30 2 Route::redirect('/app', '/dashboard') ; // Permanent redirect to a different URL, , HTTP status code 30 1 Route::permanentRedirect('contact', '/#contact'); $ php artisan route:list --columns=method,uri,name,action +----------------------------------------+------------+------------+------------------------------------------+ | Method | URI | Name | Action | +----------------------------------------+------------+------------+------------------------------------------+ | GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS | app | | Illuminate\Routing\RedirectController | | GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS | contact | | Illuminate\Routing\RedirectController | | GET|HEAD | dashboard | dashboard | App\Http\Controllers\DashboardController | +----------------------------------------+------------+------------+------------------------------------------+
  18. Route::view('/home', 'welcome')->name('welcome') ; // With additional dat a Route::view('/home', 'welcome',

    ['title' => 'Welcome'])->name('welcome'); $ php artisan route:list --columns=method,uri,name,action +----------------------------------------+------------+------------+------------------------------------------+ | Method | URI | Name | Action | +----------------------------------------+------------+------------+------------------------------------------+ | GET|HEAD | home | welcome | Illuminate\Routing\ViewController | +----------------------------------------+------------+------------+------------------------------------------+
  19. Route::fallback(function () { return redirect()->route('welcome') ; }) ; Route::fallback('App\Http\Controllers\AirportsController@index'); $

    php artisan route:list --columns=method,uri,name,action +----------------+-----------------------+--------+-------------------------------------------------+ | Method | URI | Name | Action | +----------------+-----------------------+--------+-------------------------------------------------+ | GET|HEAD | {fallbackPlaceholder} | | App\Http\Controllers\AirportsController@index | +----------------+-----------------------+--------+-------------------------------------------------+
  20. // Befor e Route::get('customers/{customer}', ShowCustomerController::class ) ->name(‘customers.show’) ; // Afte

    r Route::get(‘customers/{customer}/details’, ShowCustomerController::class ) ->name(‘customers.show’); // Before: https://example.com/customers/ 1 $url = route('customers.show', 1) ; // After: https://example.com/customers/1/detail s $url = route('customers.show', 1) ;
  21. Route::get('customers/{customer}', ShowCustomerController::class ) ->name(‘customers.show’) ; // https://example.com/customers/ 1 $url =

    route('customers.show', 1) ; // https://example.com/customers/ 1 $url = route('customers.show', Customer::find(1)) ;
  22. Route::get('customers/{customer}', ShowCustomerController::class ) ->name(‘customers.show’) ; // https://example.com/customers/ 1 $url =

    route('customers.show', 1) ; // https://example.com/customers/ 1 $url = route('customers.show', $customer) ; // https://example.com/customers/1?withInvoice= 1 $url = route('customers.show', ['customer' => $customer, 'withInvoice' => true]) ;
  23. Route::get('customers/{customer}', ShowCustomerController::class ) ->name(‘customers.show’) ; // https://example.com/customers/ 1 $url =

    route('customers.show', 1) ; // https://example.com/customers/ 1 $url = route('customers.show', $customer) ; // https://example.com/customers/1?withInvoice= 1 $url = route('customers.show', ['customer' => $customer, 'withInvoice' => true]) ; // https://example.com/customers/1?signatur e $url = route('customers.show', [$customer, 'signature']) ;
  24. Route::get('customers/{customer}', ShowCustomerController::class ) ->name(‘customers.show’) ; // https://example.com/customers/ 1 $url =

    route('customers.show', 1) ; // https://example.com/customers/ 1 $url = route('customers.show', $customer) ; // https://example.com/customers/1?withInvoice= 1 $url = route('customers.show', ['customer' => $customer, 'withInvoice' => true]) ; // https://example.com/customers/1?signatur e $url = route('customers.show', [$customer, 'signature']) ;
  25. public function handle(Request $request, Closure $next ) { if (!

    Auth::check() && $request->route()->named('customers.show')) { return redirect()->route('dashboard') ; } return $next($request) ; }
  26. Route::get('/users/{user}', [UsersController::class, ‘show'])->name('users.show') ; // Illuminate\Routing\Rout e $current = Route::current()

    ; // users.nam e $name = Route::currentRouteName() ; // App\Http\Controllers\UsersController@sho w $action = Route::currentRouteAction() ;
  27. // public/index.ph p / * |------------------------------------------------------------------------- - | Run The

    Applicatio n |------------------------------------------------------------------------- - | | Once we have the application, we can handle the incoming request usin g | the application's HTTP kernel. Then, we will send the response bac k | to this client's browser, allowing them to enjoy our application . | * / $app = require_once __DIR__.'/../bootstrap/app.php' ; $kernel = $app->make(Kernel::class) ; $response = tap($kernel->handle ( $request = Request::capture( ) ))->send() ; $kernel->terminate($request, $response) ;
  28. // app/Http/Kernel.ph p namespace App\Http ; use Illuminate\Foundation\Http\Kernel as HttpKernel

    ; class Kernel extends HttpKerne l { /* * * The application's global HTTP middleware stack . * These middleware are run during every request to your application . * / protected $middleware = [ ] ; /* * * The application's route middleware groups . * / protected $middlewareGroups = [ ] ; /* * * The application's route middleware . * These middleware may be assigned to groups or used individually . * / protected $routeMiddleware = [ ] ; }
  29. // app/Http/Kernel.ph p namespace App\Http ; use Illuminate\Foundation\Http\Kernel as HttpKernel

    ; class Kernel extends HttpKerne l { /* * * The application's global HTTP middleware stack . * * These middleware are run during every request to your application . * * @var arra y * / protected $middleware = [ // \App\Http\Middleware\TrustHosts::class , \App\Http\Middleware\TrustProxies::class , \Fruitcake\Cors\HandleCors::class , \App\Http\Middleware\PreventRequestsDuringMaintenance::class , \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class , \App\Http\Middleware\TrimStrings::class , \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class , ] ; }
  30. // app/Http/Kernel.ph p namespace App\Http ; use Illuminate\Foundation\Http\Kernel as HttpKernel

    ; class Kernel extends HttpKerne l { /* * * The application's route middleware groups . * / protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class , \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class , \Illuminate\Session\Middleware\StartSession::class , // \Illuminate\Session\Middleware\AuthenticateSession::class , \Illuminate\View\Middleware\ShareErrorsFromSession::class , \App\Http\Middleware\VerifyCsrfToken::class , \Illuminate\Routing\Middleware\SubstituteBindings::class , ] , 'api' => [ 'throttle:api' , \Illuminate\Routing\Middleware\SubstituteBindings::class , ] , ] ; }
  31. // app/Http/Kernel.ph p namespace App\Http ; use Illuminate\Foundation\Http\Kernel as HttpKernel

    ; class Kernel extends HttpKerne l { /* * * The application's route middleware . * * These middleware may be assigned to groups or used individually . * * @var arra y * / protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class , 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class , 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class , 'can' => \Illuminate\Auth\Middleware\Authorize::class , 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class , 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class , 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class , 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class , 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class , ] ; }
  32. // app/Http/Kernel.ph p namespace App\Http ; use Illuminate\Foundation\Http\Kernel as HttpKernel

    ; class Kernel extends HttpKerne l { /* * * The application's global HTTP middleware stack . * These middleware are run during every request to your application . * / protected $middleware = [ ] ; /* * * The application's route middleware groups . * / protected $middlewareGroups = [ ] ; /* * * The application's route middleware . * These middleware may be assigned to groups or used individually . * / protected $routeMiddleware = [ ] ; }
  33. // vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.ph p namespace Illuminate\Foundation\Http ; class Kernel implements KernelContrac

    t { public function handle($request ) { try { $request->enableHttpMethodParameterOverride() ; $response = $this->sendRequestThroughRouter($request) ; } catch (Throwable $e) { $this->reportException($e) ; $response = $this->renderException($request, $e) ; } $this->app['events']->dispatch ( new RequestHandled($request, $response ) ) ; return $response ; } }
  34. // vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.ph p namespace Illuminate\Foundation\Http ; class Kernel implements KernelContrac

    t { /* * * Send the given request through the middleware / router . * * @param \Illuminate\Http\Request $reques t * @return \Illuminate\Http\Respons e * / protected function sendRequestThroughRouter($request ) { $this->app->instance('request', $request) ; Facade::clearResolvedInstance('request') ; $this->bootstrap() ; return (new Pipeline($this->app) ) ->send($request ) ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware ) ->then($this->dispatchToRouter()) ; } }
  35. // vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.ph p namespace Illuminate\Foundation\Http ; class Kernel implements KernelContrac

    t { /* * * Send the given request through the middleware / router . * * @param \Illuminate\Http\Request $reques t * @return \Illuminate\Http\Respons e * / protected function sendRequestThroughRouter($request ) { $this->app->instance('request', $request) ; Facade::clearResolvedInstance('request') ; $this->bootstrap() ; return (new Pipeline($this->app) ) ->send($request ) ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware ) ->then($this->dispatchToRouter()) ; } }
  36. // app/Providers/RouteServiceProvider.ph p namespace App\Providers ; use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider

    ; class RouteServiceProvider extends ServiceProvide r { /* * * Define your route model bindings, pattern filters, etc . * * @return voi d * / public function boot( ) { $this->configureRateLimiting() ; $this->routes(function () { Route::prefix('api' ) ->middleware('api' ) ->namespace($this->namespace ) ->group(base_path('routes/api.php')) ; Route::middleware('web' ) ->namespace($this->namespace ) ->group(base_path('routes/web.php')) ; }) ; } }
  37. // vendor/laravel/framework/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.ph p namespace Illuminate\Foundation\Support\Providers ; class RouteServiceProvider extends ServiceProvide

    r { /* * * Register the callback that will be used to load the application's routes . * * @param \Closure $routesCallbac k * @return $thi s * / protected function routes(Closure $routesCallback ) { $this->loadRoutesUsing = $routesCallback ; return $this ; } }
  38. // vendor/laravel/framework/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.ph p namespace Illuminate\Foundation\Support\Providers ; class RouteServiceProvider extends ServiceProvide

    r { /* * * Register any application services . * * @return voi d * / public function register( ) { $this->booted(function () { $this->setRootControllerNamespace() ; if ($this->routesAreCached()) { $this->loadCachedRoutes() ; } else { $this->loadRoutes() ; $this->app->booted(function () { $this->app['router']->getRoutes()->refreshNameLookups() ; $this->app['router']->getRoutes()->refreshActionLookups() ; }) ; } }) ; } }
  39. // vendor/laravel/framework/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.ph p namespace Illuminate\Foundation\Support\Providers ; class RouteServiceProvider extends ServiceProvide

    r { /* * * Load the application routes . * * @return voi d * / protected function loadRoutes( ) { if (! is_null($this->loadRoutesUsing)) { $this->app->call($this->loadRoutesUsing) ; } elseif (method_exists($this, 'map')) { $this->app->call([$this, 'map']) ; } } }
  40. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContract { /* * * Register a new GET route with the router . * * @return \Illuminate\Routing\Rout e * / public function get($uri, $action = null ) { return $this->addRoute(['GET', 'HEAD'], $uri, $action) ; } /* * * Register a new POST route with the router . * * @return \Illuminate\Routing\Rout e * / public function post($uri, $action = null ) { return $this->addRoute('POST', $uri, $action) ; } }
  41. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContract { /* * * Add a route to the underlying route collection . * * @param array|string $method s * @param string $ur i * @param array|string|callable|null $actio n * @return \Illuminate\Routing\Rout e * / public function addRoute($methods, $uri, $action ) { return $this->routes->add($this->createRoute($methods, $uri, $action)) ; } }
  42. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContract { protected function createRoute($methods, $uri, $action ) { // If the route is routing to a controller we will parse the route action int o // an acceptable array format before registering i t if ($this->actionReferencesController($action)) { $action = $this->convertToControllerAction($action) ; } $route = $this->newRoute ( $methods, $this->prefix($uri), $actio n ) ; // If we have groups that need to be merged, we will merge them now after thi s // route has already been created and is ready to go . if ($this->hasGroupStack()) { $this->mergeGroupAttributesIntoRoute($route) ; } $this->addWhereClausesToRoute($route) ; return $route ; } }
  43. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContract { /* * * Add a route to the underlying route collection . * * @param array|string $method s * @param string $ur i * @param array|string|callable|null $actio n * @return \Illuminate\Routing\Rout e * / public function addRoute($methods, $uri, $action ) { return $this->routes->add($this->createRoute($methods, $uri, $action)) ; } }
  44. // vendor/laravel/framework/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.ph p namespace Illuminate\Foundation\Support\Providers ; class RouteServiceProvider extends ServiceProvide

    r { /* * * Register any application services . * * @return voi d * / public function register( ) { $this->booted(function () { $this->setRootControllerNamespace() ; if ($this->routesAreCached()) { $this->loadCachedRoutes() ; } else { $this->loadRoutes() ; $this->app->booted(function () { $this->app['router']->getRoutes()->refreshNameLookups() ; $this->app['router']->getRoutes()->refreshActionLookups() ; }) ; } }) ; } }
  45. // vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.ph p namespace Illuminate\Foundation\Http ; class Kernel implements KernelContrac

    t { /* * * Send the given request through the middleware / router . * * @param \Illuminate\Http\Request $reques t * @return \Illuminate\Http\Respons e * / protected function sendRequestThroughRouter($request ) { $this->app->instance('request', $request) ; Facade::clearResolvedInstance('request') ; $this->bootstrap() ; return (new Pipeline($this->app) ) ->send($request ) ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware ) ->then($this->dispatchToRouter()) ; } }
  46. // vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.ph p namespace Illuminate\Foundation\Http ; class Kernel implements KernelContrac

    t { /* * * The router instance . * * @var \Illuminate\Routing\Route r * / protected $router ; /* * * Get the route dispatcher callback . * * @return \Closur e * / protected function dispatchToRouter( ) { return function ($request) { $this->app->instance('request', $request) ; return $this->router->dispatch($request) ; } ; } }
  47. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * Dispatch the request to the application . * * @param \Illuminate\Http\Request $reques t * @return \Symfony\Component\HttpFoundation\Respons e * / public function dispatch(Request $request ) { $this->currentRequest = $request ; return $this->dispatchToRoute($request) ; } /* * * Dispatch the request to a route and return the response . * / public function dispatchToRoute(Request $request ) { return $this->runRoute($request, $this->findRoute($request)) ; } }
  48. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * The route collection instance . * * @var \Illuminate\Routing\RouteCollectionInterfac e * / protected $routes ; /* * * Find the route matching a given request . * * @param \Illuminate\Http\Request $reques t * @return \Illuminate\Routing\Rout e * / protected function findRoute($request ) { $this->current = $route = $this->routes->match($request) ; $this->container->instance(Route::class, $route) ; return $route ; } }
  49. // vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.ph p namespace Illuminate\Routing ; class RouteCollection extends AbstractRouteCollectio

    n { /* * * Find the first route matching a given request . * * @param \Illuminate\Http\Request $reques t * @return \Illuminate\Routing\Rout e * * @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpExceptio n * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpExceptio n * / public function match(Request $request ) { $routes = $this->get($request->getMethod()) ; // First, we will see if we can find a matching route for this current reques t // method. If we can, great, we can just return it so that it can be calle d // by the consumer. Otherwise we will check for routes with another verb . $route = $this->matchAgainstRoutes($routes, $request) ; return $this->handleMatchedRoute($request, $route) ; } }
  50. // vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.ph p namespace Illuminate\Routing ; class RouteCollection extends AbstractRouteCollectio

    n { /* * * Determine if a route in the array matches the request . * * @return \Illuminate\Routing\Route|nul l * / protected function matchAgainstRoutes(array $routes, $request, $includingMethod = true ) { [$fallbacks, $routes] = collect($routes)->partition(function ($route) { return $route->isFallback ; }) ; return $routes->merge($fallbacks)->first(function (Route $route) use ($request, $includin { return $route->matches($request, $includingMethod) ; }) ; } }
  51. // vendor/laravel/framework/src/Illuminate/Routing/Route.ph p namespace Illuminate\Routing ; class Route { /*

    * * Determine if the route matches a given request . * * @return boo l * / public function matches(Request $request, $includingMethod = true ) { $this->compileRoute() ; foreach (self::getValidators() as $validator) { if (! $includingMethod && $validator instanceof MethodValidator) { continue ; } if (! $validator->matches($this, $request)) { return false ; } } return true ; } }
  52. // vendor/laravel/framework/src/Illuminate/Routing/Route.ph p namespace Illuminate\Routing ; class Route { /*

    * * Compile the route into a Symfony CompiledRoute instance . * / protected function compileRoute( ) { if (! $this->compiled) { $this->compiled = $this->toSymfonyRoute()->compile() ; } return $this->compiled ; } public function toSymfonyRoute( ) { return new SymfonyRoute ( preg_replace('/\{(\w+?)\?\}/', '{$1}', $this->uri()), $this->getOptionalParameterNames() , $this->wheres, ['utf8' => true, 'action' => $this->action] , $this->getDomain() ?: '', [], $this->method s ) ; } }
  53. // vendor/laravel/framework/src/Illuminate/Routing/Route.ph p namespace Illuminate\Routing ; class Route { /*

    * * Determine if the route matches a given request . * * @return boo l * / public function matches(Request $request, $includingMethod = true ) { $this->compileRoute() ; foreach (self::getValidators() as $validator) { if (! $includingMethod && $validator instanceof MethodValidator) { continue ; } if (! $validator->matches($this, $request)) { return false ; } } return true ; } }
  54. // vendor/laravel/framework/src/Illuminate/Routing/Route.ph p namespace Illuminate\Routing ; class Route { /*

    * * Get the route validators for the instance . * * @return arra y * / public static function getValidators( ) { if (isset(static::$validators)) { return static::$validators ; } // To match the route, we will use a chain of responsibility pattern with th e // validator implementations. We will spin through each one making sure i t // passes and then we will know if the route as a whole matches request . return static::$validators = [ new UriValidator, new MethodValidator , new SchemeValidator, new HostValidator , ] ; } }
  55. // vendor/laravel/framework/src/Illuminate/Routing/Matching/UriValidator.ph p namespace Illuminate\Routing\Matching ; use Illuminate\Http\Request ; use

    Illuminate\Routing\Route ; class UriValidator implements ValidatorInterfac e { /* * * Validate a given rule against a route and request . * * @param \Illuminate\Routing\Route $rout e * @param \Illuminate\Http\Request $reques t * @return boo l * / public function matches(Route $route, Request $request ) { $path = rtrim($request->getPathInfo(), '/') ?: '/' ; return preg_match($route->getCompiled()->getRegex(), rawurldecode($path)) ; } }
  56. // vendor/laravel/framework/src/Illuminate/Routing/Route.ph p namespace Illuminate\Routing ; class Route { /*

    * * Determine if the route matches a given request . * * @return boo l * / public function matches(Request $request, $includingMethod = true ) { $this->compileRoute() ; foreach (self::getValidators() as $validator) { if (! $includingMethod && $validator instanceof MethodValidator) { continue ; } if (! $validator->matches($this, $request)) { return false ; } } return true ; } }
  57. // vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.ph p namespace Illuminate\Routing ; class RouteCollection extends AbstractRouteCollectio

    n { /* * * Find the first route matching a given request . * * @param \Illuminate\Http\Request $reques t * @return \Illuminate\Routing\Rout e * * @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpExceptio n * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpExceptio n * / public function match(Request $request ) { $routes = $this->get($request->getMethod()) ; // First, we will see if we can find a matching route for this current reques t // method. If we can, great, we can just return it so that it can be calle d // by the consumer. Otherwise we will check for routes with another verb . $route = $this->matchAgainstRoutes($routes, $request) ; return $this->handleMatchedRoute($request, $route) ; } }
  58. // vendor/laravel/framework/src/Illuminate/Routing/AbstractRouteCollection.ph p namespace Illuminate\Routing ; abstract class AbstractRouteCollection {

    protected function handleMatchedRoute(Request $request, $route ) { if (! is_null($route)) { return $route->bind($request) ; } // If no route was found we will now check if a matching route is specified b y // another HTTP verb. If it is we will need to throw a MethodNotAllowed an d // inform the user agent of which HTTP verb it should use for this route . $others = $this->checkForAlternateVerbs($request) ; if (count($others) > 0) { return $this->getRouteForMethods($request, $others) ; } throw new NotFoundHttpException ; } }
  59. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * The route collection instance . * * @var \Illuminate\Routing\RouteCollectionInterfac e * / protected $routes ; /* * * Find the route matching a given request . * * @param \Illuminate\Http\Request $reques t * @return \Illuminate\Routing\Rout e * / protected function findRoute($request ) { $this->current = $route = $this->routes->match($request) ; $this->container->instance(Route::class, $route) ; return $route ; } }
  60. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * Dispatch the request to the application . * * @param \Illuminate\Http\Request $reques t * @return \Symfony\Component\HttpFoundation\Respons e * / public function dispatch(Request $request ) { $this->currentRequest = $request ; return $this->dispatchToRoute($request) ; } /* * * Dispatch the request to a route and return the response . * / public function dispatchToRoute(Request $request ) { return $this->runRoute($request, $this->findRoute($request)) ; } }
  61. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * Return the response for the given route . * * @param \Illuminate\Http\Request $reques t * @param \Illuminate\Routing\Route $rout e * @return \Symfony\Component\HttpFoundation\Respons e * / protected function runRoute(Request $request, Route $route ) { $request->setRouteResolver(function () use ($route) { return $route ; }) ; $this->events->dispatch(new RouteMatched($route, $request)) ; return $this->prepareResponse($request , $this->runRouteWithinStack($route, $request ) ) ; } }
  62. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * Run the given route within a Stack "onion" instance . * / protected function runRouteWithinStack(Route $route, Request $request ) { $shouldSkipMiddleware = $this->container->bound('middleware.disable') & & $this->container->make('middleware.disable') === true ; $middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route) ; return (new Pipeline($this->container) ) ->send($request ) ->through($middleware ) ->then(function ($request) use ($route) { return $this->prepareResponse ( $request, $route->run( ) ) ; }) ; }
  63. // vendor/laravel/framework/src/Illuminate/Routing/Route.ph p namespace Illuminate\Routing ; class Rout e {

    /* * * Run the route action and return the response . * * @return mixe d * / public function run( ) { $this->container = $this->container ?: new Container ; try { if ($this->isControllerAction()) { return $this->runController() ; } return $this->runCallable() ; } catch (HttpResponseException $e) { return $e->getResponse() ; } } }
  64. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * Run the given route within a Stack "onion" instance . * / protected function runRouteWithinStack(Route $route, Request $request ) { $shouldSkipMiddleware = $this->container->bound('middleware.disable') & & $this->container->make('middleware.disable') === true ; $middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route) ; return (new Pipeline($this->container) ) ->send($request ) ->through($middleware ) ->then(function ($request) use ($route) { return $this->prepareResponse ( $request, $route->run( ) ) ; }) ; }
  65. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * Create a response instance from the given value . * * @param \Symfony\Component\HttpFoundation\Request $reques t * @param mixed $respons e * @return \Symfony\Component\HttpFoundation\Respons e * / public function prepareResponse($request, $response ) { return static::toResponse($request, $response) ; } /* * * Static version of prepareResponse . * * @param \Symfony\Component\HttpFoundation\Request $reques t * @param mixed $respons e * @return \Symfony\Component\HttpFoundation\Respons e * / public static function toResponse($request, $response ) { if ($response instanceof Responsable) { $response = $response->toResponse($request) ; }
  66. * / public static function toResponse($request, $response ) { if

    ($response instanceof Responsable) { $response = $response->toResponse($request) ; } if ($response instanceof PsrResponseInterface) { $response = (new HttpFoundationFactory)->createResponse($response) ; } elseif ($response instanceof Model && $response->wasRecentlyCreated) { $response = new JsonResponse($response, 201) ; } elseif ($response instanceof Stringable) { $response = new Response($response->__toString(), 200, ['Content-Type' => 'text/html']) ; } elseif (! $response instanceof SymfonyResponse & & ($response instanceof Arrayable | | $response instanceof Jsonable | | $response instanceof ArrayObject | | $response instanceof JsonSerializable | | is_array($response))) { $response = new JsonResponse($response) ; } elseif (! $response instanceof SymfonyResponse) { $response = new Response($response, 200, ['Content-Type' => 'text/html']) ; } if ($response->getStatusCode() === Response::HTTP_NOT_MODIFIED) { $response->setNotModified() ; } return $response->prepare($request) ; }
  67. // vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.ph p namespace Illuminate\Foundation\Http ; class Kernel implements KernelContrac

    t { public function handle($request ) { try { $request->enableHttpMethodParameterOverride() ; $response = $this->sendRequestThroughRouter($request) ; } catch (Throwable $e) { $this->reportException($e) ; $response = $this->renderException($request, $e) ; } $this->app['events']->dispatch ( new RequestHandled($request, $response ) ) ; return $response ; } }
  68. Route::get('/airports/{airport}', [AirportsController::class, ‘show'] ) ->name(‘airports.show') ; use App\Models\Airport ; class

    AirportsController extends Controlle r { public function show(Airport $airport ) { return $airport ; } } Route::get('/airports/{airport}', function (Airport $airport) { return $airport ; })->name('airports.show') ;
  69. // https://example.com/airports/ 1 Route::get('/airports/{airport}', function (Airport $airport) { // \App\Models\Airpor

    t return $airport ; })->name('airports.show'); // https://example.com/airports/ 1 Route::get('/airports/{airport}', function ($airport) { // 1 return $airport ; })->name('airports.show');
  70. Route::get('users/{username}', function ($name) { return $name ; })->where('username', '[A-Za-z]+')->name('users.show') ;

    Route::get('{twitter}', function ($twitter) { return $twitter ; })->where('twitter', '^@(\w){1,15}$')->name('twitter') ; $ php artisan route:list +--------+----------+------------------+------------+---------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+------------------+------------+---------+------------+ | | GET|HEAD | users/{username} | users.show | Closure | web | | | GET|HEAD | {twitter} | twitter | Closure | web | +--------+----------+------------------+------------+---------+------------+
  71. Route::get('users/{id}', [UsersController::class, 'show'] ) ->whereNumber('id' ) ->name('users.show') ; Route::get('users/{username}', [UsersController::class,

    'show'] ) ->whereAlpha('username' ) ->name('users.show') ; Route::get('users/{username}', [UsersController::class, 'show'] ) ->whereAlphaNumeric('username' ) ->name('users.show') ; Route::get('users/{id}', [UsersController::class, 'show'] ) ->whereUuid('id' ) ->name('users.show');
  72. use App\Models\Airport ; class AirportsController extends Controlle r { public

    function show(?Airport $airport = null ) { if ($airport === null) { return Airport::first() ; } return $airport ; } } Route::get(‘/airports/{airport?}', [AirportsController::class, ‘show’] ) ->name('airports.show');
  73. namespace App\Models ; final class Airport extends Mode l {

    use HasFactory ; /* * * Get the route key for the model . * * @return strin g * / public function getRouteKeyName(): strin g { return 'code' ; } } // https://example.com/airports/AM S Route::get('/airports/{airport}', [AirportsController::class, ‘show’] ) ->name('airports.show');
  74. // app/Providers/RouteServiceProvider.ph p namespace App\Providers ; class RouteServiceProvider extends ServiceProvide

    r { /* * * Define your route model bindings, pattern filters, etc . * * @return voi d * / public function boot( ) { Route::model('airport', Airport::class) ; Route::model('code', Airport::class) ; } } // https://example.com/airports/AM S Route::get('/airports/{airport}', [AirportsController::class, ‘show’] ) ->name(‘airports.show') ; Route::get('/airports/{code}', [AirportsController::class, ‘show’] ) ->name(‘airports.show’);
  75. // app/Providers/RouteServiceProvider.ph p namespace App\Providers ; class RouteServiceProvider extends ServiceProvide

    r { /* * * Define your route model bindings, pattern filters, etc . * * @return voi d * / public function boot( ) { Route::bind(‘airport', function ($value) { return Airport::where('code', $value ) ->orWhere('id', $value ) ->orWhere('uuid', $value ) ->firstOrFail() ; }) ; } }
  76. namespace App\Models ; final class Airport extends Mode l {

    public function resolveRouteBinding($value, $field = null): sel f { return $this->where('code', $value ) ->orWhere('id', $value ) ->orWhere('uuid', $value ) ->firstOrFail() ; } }
  77. // app/Http/Kernel.ph p namespace App\Http; class Kernel extends HttpKerne l

    { /* * * The application's route middleware groups . * * @var arra y * / protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class , \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class , \Illuminate\Session\Middleware\StartSession::class , // \Illuminate\Session\Middleware\AuthenticateSession::class , \Illuminate\View\Middleware\ShareErrorsFromSession::class , \App\Http\Middleware\VerifyCsrfToken::class , \Illuminate\Routing\Middleware\SubstituteBindings::class , ] , 'api' => [ 'throttle:api' , \Illuminate\Routing\Middleware\SubstituteBindings::class , ] , ] ; }
  78. // vendor/laravel/framework/src/Illuminate/Routing/Middeware/SubstituteBindings.ph p namespace Illuminate\Routing\Middleware; class SubstituteBindings { /** *

    Handle an incoming request. */ public function handle($request, Closure $next) { try { $this->router->substituteBindings($route = $request->route()); $this->router->substituteImplicitBindings($route); } catch (ModelNotFoundException $exception) { if ($route->getMissing()) { return $route->getMissing()($request); } throw $exception; } return $next($request); } }
  79. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { public function substituteBindings($route ) { foreach ($route->parameters() as $key => $value) { if (isset($this->binders[$key])) { $route->setParameter($key, $this->performBinding($key, $value, $route)) ; } } return $route ; } /** * Call the binding callback for the given key. */ protected function performBinding($key, $value, $route) { return call_user_func($this->binders[$key], $value, $route); } }
  80. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { public function substituteBindings($route ) { foreach ($route->parameters() as $key => $value) { if (isset($this->binders[$key])) { $route->setParameter($key, $this->performBinding($key, $value, $route)) ; } } return $route ; } /** * Call the binding callback for the given key. */ protected function performBinding($key, $value, $route) { return call_user_func($this->binders[$key], $value, $route); } }
  81. // app/Providers/RouteServiceProvider.ph p namespace App\Providers ; class RouteServiceProvider extends ServiceProvide

    r { /* * * Define your route model bindings, pattern filters, etc . * / public function boot( ) { Route::model('code', Airport::class) ; Route::bind('airport', function ($value) { return Airport::where('code', $value ) ->orWhere('id', $value ) ->orWhere('uuid', $value ) ->firstOrFail() ; }) ; } }
  82. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * Add a new route parameter binder . * / public function bind($key, $binder ) { $this->binders[str_replace('-', '_', $key)] = RouteBinding::forCallback ( $this->container, $binde r ) ; } /* * * Register a model binder for a wildcard . * / public function model($key, $class, Closure $callback = null ) { $this->bind($key, RouteBinding::forModel($this->container, $class, $callback)) ; } }
  83. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph d Route::bind('airport', App\Services\AirportBinder::class) ; // Calls the method

    of the clas s Route::bind('airport', ‘App\Services\AirportBinder@parse') ; // Use the callback Route::bind('airport', function ($value) { return Airport::where('code', $value ) ->orWhere('id', $value ) ->firstOrFail() ; });
  84. // vendor/laravel/framework/src/Illuniate/Routing/RouteBinding.ph p namespace Illuminate\Routing ; class RouteBindin g {

    public static function forCallback($container, $binder ) { if (is_string($binder)) { return static::createClassBinding($container, $binder) ; } return $binder ; } protected static function createClassBinding($container, $binding ) { return function ($value, $route) use ($container, $binding) { // If the binding has an @ sign, we will assume it's being used to delimi t // the class name from the bind method name. This allows for binding s // to run multiple bind methods in a single class for convenience . [$class, $method] = Str::parseCallback($binding, 'bind') ; $callable = [$container->make($class), $method] ; return $callable($value, $route) ; } ; } }
  85. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * Add a new route parameter binder . * / public function bind($key, $binder ) { $this->binders[str_replace('-', '_', $key)] = RouteBinding::forCallback ( $this->container, $binde r ) ; } /* * * Register a model binder for a wildcard . * / public function model($key, $class, Closure $callback = null ) { $this->bind($key, RouteBinding::forModel($this->container, $class, $callback)) ; } }
  86. // vendor/laravel/framework/src/Illuniate/Routing/RouteBinding.ph p namespace Illuminate\Routing ; class RouteBindin g {

    public static function forModel($container, $class, $callback = null ) { return function ($value) use ($container, $class, $callback) { if (is_null($value)) { return ; } // Try to find the model and return it . $instance = $container->make($class) ; if ($model = $instance->resolveRouteBinding($value)) { return $model ; } // Callback to determine what should happen if model was not found . if ($callback instanceof Closure) { return $callback($value) ; } throw (new ModelNotFoundException)->setModel($class) ; } ; } }
  87. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * Add a new route parameter binder . * / public function bind($key, $binder ) { $this->binders[str_replace('-', '_', $key)] = RouteBinding::forCallback ( $this->container, $binde r ) ; } /* * * Register a model binder for a wildcard . * / public function model($key, $class, Closure $callback = null ) { $this->bind($key, RouteBinding::forModel($this->container, $class, $callback)) ; } }
  88. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { public function substituteBindings($route ) { foreach ($route->parameters() as $key => $value) { if (isset($this->binders[$key])) { $route->setParameter($key, $this->performBinding($key, $value, $route)) ; } } return $route ; } /** * Call the binding callback for the given key. */ protected function performBinding($key, $value, $route) { return call_user_func($this->binders[$key], $value, $route); } }
  89. // vendor/laravel/framework/src/Illuminate/Routing/Router.ph p namespace Illuminate\Routing ; class Router implements BindingRegistrar,

    RegistrarContrac t { /* * * Substitute the implicit Eloquent model bindings for the route . * / public function substituteImplicitBindings($route ) { ImplicitRouteBinding::resolveForRoute($this->container, $route) ; } }
  90. // vendor/laravel/framework/src/Illuminate/Routing/ImplicitRouteBinding.ph p namespace Illuminate\Routing ; class ImplicitRouteBindin g {

    public static function resolveForRoute($container, $route ) { $parameters = $route->parameters() ; foreach ($route->signatureParameters(UrlRoutable::class) as $parameter) { if (! $parameterName = static::getParameterName($parameter->getName(), $parameters)) { continue ; } $parameterValue = $parameters[$parameterName] ; if ($parameterValue instanceof UrlRoutable) { continue ; } $instance = $container->make(Reflector::getParameterClassName($parameter)) ; $parent = $route->parentOfParameter($parameterName) ; if ($parent instanceof UrlRoutable && in_array($parameterName, array_keys($route- >bindingFields()))) { if (! $model = $parent->resolveChildRouteBinding ( $parameterName, $parameterValue, $route->bindingFieldFor($parameterName ) {
  91. // vendor/laravel/framework/src/Illuminate/Routing/Route.ph p namespace Illuminate\Routing ; class Rout e {

    /** * Get the parameters that are listed in the route / controller signature. * * @param string|null $subClass * @return array */ public function signatureParameters($subClass = null) { return RouteSignatureParameters::fromAction($this->action, $subClass); } }
  92. // vendor/laravel/framework/src/Illuminate/Routing/RouteSignatureParameters.php namespace Illuminate\Routing; class RouteSignatureParameters { public static function

    fromAction(array $action, $subClass = null) { $callback = RouteAction::containsSerializedClosure($action) ? unserialize($action['uses'])->getClosure() : $action['uses']; $parameters = is_string($callback) ? static::fromClassMethodString($callback) : (new ReflectionFunction($callback))->getParameters(); return is_null($subClass) ? $parameters : array_filter($parameters, function ($p) use ($subClass) { return Reflector::isParameterSubclassOf($p, $subClass); }); } protected static function fromClassMethodString($uses) { [$class, $method] = Str::parseCallback($uses); if (! method_exists($class, $method) && Reflector::isCallable($class, $method)) { return []; } return (new ReflectionMethod($class, $method))->getParameters(); } }
  93. // vendor/laravel/framework/src/Illuminate/Routing/RouteSignatureParameters.php namespace Illuminate\Routing; class RouteSignatureParameters { public static function

    fromAction(array $action, $subClass = null) { $callback = RouteAction::containsSerializedClosure($action) ? unserialize($action['uses'])->getClosure() : $action['uses']; $parameters = is_string($callback) ? static::fromClassMethodString($callback) : (new ReflectionFunction($callback))->getParameters(); return is_null($subClass) ? $parameters : array_filter($parameters, function ($p) use ($subClass) { return Reflector::isParameterSubclassOf($p, $subClass); }); } protected static function fromClassMethodString($uses) { [$class, $method] = Str::parseCallback($uses); if (! method_exists($class, $method) && Reflector::isCallable($class, $method)) { return []; } return (new ReflectionMethod($class, $method))->getParameters(); } }
  94. { $parameters = $route->parameters() ; foreach ($route->signatureParameters(UrlRoutable::class) as $parameter) {

    if (! $parameterName = static::getParameterName($parameter->getName(), $parameters)) { continue ; } $parameterValue = $parameters[$parameterName] ; if ($parameterValue instanceof UrlRoutable) { continue ; } $instance = $container->make(Reflector::getParameterClassName($parameter)) ; $parent = $route->parentOfParameter($parameterName) ; if ($parent instanceof UrlRoutable && in_array($parameterName, array_keys($route->bindingFields()))) { if (! $model = $parent->resolveChildRouteBinding ( $parameterName, $parameterValue, $route->bindingFieldFor($parameterName ) )) { throw (new ModelNotFoundException)->setModel(get_class($instance), [$parameterValue]) ; } } elseif (! $model = $instance->resolveRouteBinding($parameterValue, $route- >bindingFieldFor($parameterName))) { throw (new ModelNotFoundException)->setModel(get_class($instance), [$parameterValue]) ; } $route->setParameter($parameterName, $model) ; } }
  95. // vendor/laravel/framework/src/Illuminate/Routing/Middeware/SubstituteBindings.ph p namespace Illuminate\Routing\Middleware ; class SubstituteBinding s {

    public function handle($request, Closure $next ) { try { $this->router->substituteBindings($route = $request->route()) ; $this->router->substituteImplicitBindings($route) ; } catch (ModelNotFoundException $exception) { if ($route->getMissing()) { return $route->getMissing()($request) ; } throw $exception ; } return $next($request) ; } }
  96. // vendor/laravel/framework/src/Illuminate/Routing/Route.ph p namespace Illuminate\Routing ; class Rout e {

    /* * * Run the route action and return the response . * * @return mixe d * / public function run( ) { $this->container = $this->container ?: new Container ; try { if ($this->isControllerAction()) { return $this->runController() ; } return $this->runCallable() ; } catch (HttpResponseException $e) { return $e->getResponse() ; } } }
  97. // vendor/laravel/framework/src/Illuminate/Routing/Route.ph p namespace Illuminate\Routing ; class Rout e {

    protected function runController() { return $this->controllerDispatcher()->dispatch( $this, $this->getController(), $this->getControllerMethod() ); } public function getController() { if (! $this->controller) { $class = $this->parseControllerCallback()[0]; $this->controller = $this->container->make(ltrim($class, '\\')); } return $this->controller; } protected function getControllerMethod() { return $this->parseControllerCallback()[1]; } protected function parseControllerCallback() { return Str::parseCallback($this->action['uses']); } }
  98. // vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php namespace Illuminate\Routing; use Illuminate\Container\Container; use Illuminate\Routing\Contracts\ControllerDispatcher as ControllerDispatcherContract;

    class ControllerDispatcher implements ControllerDispatcherContract { use RouteDependencyResolverTrait; /** * Dispatch a request to a given controller and method. */ public function dispatch(Route $route, $controller, $method) { $parameters = $this->resolveClassMethodDependencies( $route->parametersWithoutNulls(), $controller, $method ); if (method_exists($controller, 'callAction')) { return $controller->callAction($method, $parameters); } return $controller->{$method}(...array_values($parameters)); } }
  99. class OrdersController extends Controlle r { public function store(Request $request

    ) { $pattern = '/order/vendor/{vendor}/pizza/{pizza}' ; $message = json_decode($request->input('message'), true) ; $parameters = $this->getRouteParametersForPattern($message['order'], $pattern) ; $vendor = Vendor::where('key', $parameters['vendor'])->firstOrFail() ; $pizza = Pizza::where('key', $parameters['pizza'])->firstOrFail(); } } "order": "/order/vendor/dominos/pizza/hawaii",
  100. "order": "/order/vendor/dominos/pizza/hawaii", $pattern = '/order/vendor/{vendor}/pizza/{pizza}'; private function getRouteParametersForPattern(string $url, string

    $pattern): arra y { $compiledRoute = RouteCompiler::compile(new Route($pattern)) ; $matches = [] ; preg_match_all($compiledRoute->getRegex(), $url, $matches) ; $parameters = [] ; foreach ($compiledRoute->getVariables() as $variable) { $parameters[$variable] = $matches[$variable][0] ; } return $parameters ; }
  101. private function getRouteParametersForPattern(string $url, string $pattern): arra y { $compiledRoute

    = RouteCompiler::compile(new Route($pattern)) ; $matches = [] ; preg_match_all($compiledRoute->getRegex(), $url, $matches) ; $parameters = [] ; foreach ($compiledRoute->getVariables() as $variable) { $parameters[$variable] = $matches[$variable][0] ; } return $parameters ; } "order": "/order/vendor/dominos/pizza/hawaii", $pattern = '/order/vendor/{vendor}/pizza/{pizza}'; $regex = "{^/order/vendor/(?P<vendor>[^/]++)/pizza/(?P<pizza>[^/]++)$}sD" ; $matches = [ 'vendor' => [ 'dominos' , ] , 'pizza' => [ 'margherita' , ] , ];
  102. class OrdersController extends Controlle r { public function store(Request $request

    ) { $pattern = '/order/vendor/{vendor}/pizza/{pizza}' ; $message = json_decode($request->input('message'), true) ; $parameters = $this->getRouteParametersForPattern($message['order'], $pattern) ; $vendor = Vendor::where('key', $parameters['vendor'])->firstOrFail() ; $pizza = Pizza::where('key', $parameters['pizza'])->firstOrFail(); } } "order": "/order/vendor/dominos/pizza/hawaii",
  103. final class Shadow extends Messag e { public string $type

    = MessageTypes::TYPE_SHADOW_FLICKER ; protected string $routePattern = '/windpark/{windparkId}/turbine/{turbineId}/sensor/shadow_flicker' ; public function validate(): Messag e { if (! is_bool($this->message->status)) { throw new Exception('Value could not be validated') ; } return $this ; } public function isSameStatus($status): boo l { return (bool) $status === $this->message->status ; } }
  104. // Don't do thi s Route::name('teams.')->group(function () { Route::group(['prefix' =>

    'team'], function () { Route::get('/', [TeamsController::class, 'index'])->middleware('auth')->name('index') ; Route::get('/create', [TeamsController::class, 'create'])->middleware('auth')->name('create') ; Route::post('/', [TeamsController::class, 'store'])->middleware('auth')->name('store') ; Route::get('/{team}', [TeamsController::class, 'show'])->middleware('auth')->name('show') ; Route::get('/{team}/edit', [TeamsController::class, 'edit'])->middleware('auth')->name('edit') ; Route::put('/{team}', [TeamsController::class, 'update'])->middleware('auth')->name('update') ; Route::delete('/{team}', [TeamsController::class, 'destroy'])->middleware('auth')->name('destroy') ; }) ; }); // Instead do thi s Route::get('teams', [TeamsController::class, 'index'])->name('teams.index') ; Route::middleware('auth')->group(function () { Route::get('teams/create', [TeamsController::class, 'create'])->name('teams.create') ; Route::post('teams', [TeamsController::class, 'store'])->name('teams.store') ; Route::get('teams/{team}', [TeamsController::class, 'show'])->name('teams.show') ; Route::get('teams/{team}/edit', [TeamsController::class, 'edit'])->name('teams.edit') ; Route::put('teams/{team}', [TeamsController::class, 'update'])->name('teams.update') ; Route::delete('teams/{team}', [TeamsController::class, 'destroy'])->name('teams.destroy') ; });
  105. // app/Providers/RouteServiceProvider.php namespace App\Providers; class RouteServiceProvider extends ServiceProvider { /**

    * Define your route model bindings, pattern filters, etc. */ public function boot() { $this->routes(function () { Route::prefix('api') ->middleware('api') ->namespace($this->namespace) ->group(base_path('routes/api.php')); Route::middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web.php')); Route::middleware(['web', 'can:admin']) ->namespace($this->namespace) ->group(base_path('routes/admin.php')); }); } }
  106. // app/Providers/RouteServiceProvider.php namespace App\Providers; class RouteServiceProvider extends ServiceProvider { /**

    * Define your route model bindings, pattern filters, etc. */ public function boot() { $this->routes(function () { if (config('app.api') === true) { Route::prefix('api') ->middleware('api') ->namespace($this->namespace) ->group(base_path('routes/api.php')); } else { Route::middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web.php')); } }); } }
  107. // app/Providers/RouteServiceProvider.php namespace App\Providers; class RouteServiceProvider extends ServiceProvider { /**

    * Define your route model bindings, pattern filters, etc. */ public function boot() { Route::model('country', Country::class); Route::bind('airport', function ($value, $route) { return Airport::where('country_id', $route->parameter('country')) ->where('code', $value) ->firstOrFail(); }); } }
  108. // Doesn’t work as expected Route::get('/users/{user}', [UsersController::class, 'show'])->name('users.show'); Route::get('/users/create', [UsersController::class,

    'create'])->name('users.create'); // Works as expected Route::get('/users/create', [UsersController::class, 'create'])->name('users.create'); 
 Route::get('/users/{user}', [UsersController::class, 'show'])->name('users.show');
  109. class SomeMiddlewar e { public function handle($request, Closure $next )

    { // App\Model\Use r $request->route(‘user') ; return $next($request) ; } }