Poznajemy routing w Laravelu. Kontynuacja poprzednich lekcji w naszym projekcie. Zaczynajmy.
Ok, najpierw coś prostego – przekierowania:
Route::redirect('/here', '/there');
Route::redirect('/here', '/there', 301);
Route::permanentRedirect('/here', '/there');
Mamy też routes z callbackiem, które możemy dopisać pod konkretny route i konkretny HTTP verb:
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
Z ciekawszych mamy też any i match:
Route::match(['get', 'post'], '/', function () {
// ...
});
Route::any('/', function () {
// ...
});
Ok, zobaczmy na route parameters (wrzucamy do web.php):
Route::get('/user/{id}', function (string $id) {
return 'User '.$id;
});
A jak to z requestem pogodzić? Request najpierw:
Route::get('/user/{id}', function (Request $request, string $id) {
$page = $request->query('page', '1');
return 'User '.$id . ' Page: ' . $page;
});
Route params mogą być nullable:
Route::get('/user/{name?}', function (?string $name = null) {
return $name;
});
Route::get('/user/{name?}', function (?string $name = 'John') {
return $name;
});
Z drugiej strony, mogą podlegać restrykcjom określonym w regex:
Route::get('/user/{name}', function (string $name) {
// ...
})->where('name', '[A-Za-z]+');
Route::get('/user/{id}', function (string $id) {
// ...
})->where('id', '[0-9]+');
Route::get('/user/{id}/{name}', function (string $id, string $name) {
// ...
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
Mamy też pomocnicze funkcje do tego:
Route::get('/user/{id}/{name}', function (string $id, string $name) {
// ...
})->whereNumber('id')->whereAlpha('name');
Route::get('/user/{name}', function (string $name) {
// ...
})->whereAlphaNumeric('name');
Route::get('/user/{id}', function (string $id) {
// ...
})->whereUuid('id');
Route::get('/user/{id}', function (string $id) {
// ...
})->whereUlid('id');
Route::get('/category/{category}', function (string $category) {
// ...
})->whereIn('category', ['movie', 'song', 'painting']);
Route::get('/category/{category}', function (string $category) {
// ...
})->whereIn('category', CategoryEnum::cases());
W AppServiceProvider możemy stworzyć własne wzory:
use Illuminate\Support\Facades\Route;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::pattern('id', '[0-9]+');
}
Z ciekawszych rzeczy jakie widzę, jest możliwość sprawdzania nazwy route wewnątrz middleware:
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if ($request->route()->named('profile')) {
// ...
}
return $next($request);
}
A co to nazwa route? Już ją widzieliśmy, przypomnijmy:
Route::get('/faker', function () {
return view('faker');
})->name("faker");
Route::get('/faker2', FakerController::class)->name("faker2");
Route::view('/faker3', 'faker')->name('faker3');
Mamy tutaj route z callbackiem, route z invokable controllerem oraz route z widokiem, wszystkie na metodzie get i wszystkie robią mniej więcej to samo. Ta nazwa to ten „name”. Dzięki niej możemy robić redirecty do tych routes:
Route::get('/', function () {
return view('welcome2');
})->name("main");
Route::post("/", function(Request $request){
$request->validate([
'author' => 'required',
'description' => 'required'
]);
session()->flash("status", "entry created!");
return redirect()->route("main");
});
Tutaj mamy przykład redirecta do nazwanego route. Choć można do redirect przekazać string ze ścieżką relatywną, np. „/”, to też zadziała.