Skip to content

Instantly share code, notes, and snippets.

@ziadoz
Last active October 25, 2024 14:53
Show Gist options
  • Save ziadoz/dd962c017fecb84bbc09d32096cff047 to your computer and use it in GitHub Desktop.
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
<?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