Last active
October 25, 2024 14:53
-
-
Save ziadoz/dd962c017fecb84bbc09d32096cff047 to your computer and use it in GitHub Desktop.
Using Laravel 11's contextual attributes to populate a data object from POST data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Contracts\Container\Container; | |
use Illuminate\Contracts\Container\ContextualAttribute; | |
use Illuminate\Support\Facades\Route; | |
/** | |
* Create a new contextual attribute that grabs fields from the request POST data. | |
* | |
* The equivalent of doing `$request->post($key, $default)` in a controller. | |
*/ | |
#[Attribute(Attribute::TARGET_PARAMETER)] | |
class Post implements ContextualAttribute | |
{ | |
public function __construct(public string $key, public string|array|null $default = null) | |
{ | |
} | |
public static function resolve(self $attribute, Container $container): mixed | |
{ | |
return $container->make('request')->post($attribute->key, $attribute->default); | |
} | |
} | |
/** | |
* Create a simple data object that accepts some parameters. | |
* | |
* Tell Laravel which fields in the POST data they should be pulled from via the contextual attribute. | |
*/ | |
class MyUserData | |
{ | |
public function __construct( | |
#[Post('name')] public string $name, | |
#[Post('age')] public int $age, | |
#[Post('hobbies')] public array $hobbies = [], | |
) { | |
} | |
} | |
/** | |
* Create a route that returns a form. | |
*/ | |
Route::get('/user', function () { | |
$token = csrf_token(); | |
return <<<HTML | |
<form method="post"> | |
Name: <input name="name"> | |
Age: <input name="age"> | |
Hobbies: <input name="hobbies[]"><input name="hobbies[]"> | |
<input name="_token" type="hidden" value="$token"> | |
<button>Save</button> | |
</form> | |
HTML; | |
}); | |
/** | |
* Create a route that accepts the data object, and dump it and the request out for comparison. | |
* | |
* In a real application you'd have a form validator to ensure the data is valid. | |
*/ | |
Route::post('/user', function (MyUserData $data) { | |
dump(request()->post(), $data); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment