dittto/symfony-custom-request
Installation Add the package via Composer:
composer require dittto/symfony-custom-request
If the package isn't on Packagist, add the GitHub repo to composer.json:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/dittto/symfony-custom-request"
}
]
Register the Bundle
Add the bundle to AppKernel.php (or Kernel.php in Symfony 4+):
new Dittto\CustomRequestBundle\DitttoCustomRequestBundle(),
Create Your First Custom Request
Define a custom request class (e.g., src/Request/TestRequest.php):
use Dittto\CustomRequestBundle\Request\CustomRequest;
class TestRequest extends CustomRequest
{
public function validate()
{
return $this->query->has('token') && $this->query->get('token') === 'allowed';
}
}
Use in Controller Inject the custom request into your controller:
use App\Request\TestRequest;
class MyController extends AbstractController
{
public function index(TestRequest $request)
{
// Request is validated; proceed with confidence
}
}
Scenario: Validate a query parameter (token) before processing a request.
Steps:
TestRequest as shown above.Service Registration
Define custom requests as services in config/services.yaml (Symfony 4+) or app/config/services.yml:
services:
App\Request\TestRequest:
arguments:
$query: '@request_stack'
tags: ['dittto.custom_request']
dittto.custom_request for automatic validation.Dependency Injection
public function __construct(TestRequest $request) { ... }
AppServiceProvider:
public function register()
{
$this->app->bind(TestRequest::class, function ($app) {
return new TestRequest($app['request']);
});
}
Validation Logic
Extend CustomRequest and override validate():
public function validate()
{
// Example: Validate POST data + external API
if (!$this->request->isMethod('post')) {
return false;
}
$data = $this->request->request->all();
if (empty($data['email'])) {
return false;
}
// Call external service (e.g., via HTTP client)
$apiResponse = $this->apiClient->validateEmail($data['email']);
return $apiResponse['valid'];
}
Reusing Validation Logic
UserRepository, ApiClient) into custom requests:
class UserRequest extends CustomRequest
{
public function __construct(
Request $request,
UserRepository $userRepo
) {
$this->userRepo = $userRepo;
parent::__construct($request);
}
public function validate()
{
$user = $this->userRepo->find($this->query->get('id'));
return $user && $user->isActive();
}
}
services:
App\Request\UserRequest:
arguments:
$userRepo: '@App\Repository\UserRepository'
tags: ['dittto.custom_request']
Controller Integration
public function show(UserRequest $request)
{
$userId = $request->query->get('id');
// Proceed with validated data
}
Laravel-Specific:
Request with Laravel’s Illuminate\Http\Request in custom requests:
use Illuminate\Http\Request;
class LaravelCustomRequest extends CustomRequest
{
public function __construct(Request $request) { ... }
}
AppServiceProvider:
$this->app->bind(LaravelCustomRequest::class, function ($app) {
return new LaravelCustomRequest($app->make(Request::class));
});
Validation Layers: Combine with Laravel’s built-in validation (e.g., Form Requests) for layered validation:
// In a Form Request
public function authorize() {
return true; // Always pass
}
public function rules() {
return [
'email' => 'required|email',
];
}
// In CustomRequest
public function validate() {
$validator = Validator::make($this->request->all(), ['email' => 'required']);
return !$validator->fails();
}
Error Handling:
false in validate().try {
$this->index($request);
} catch (InvalidRequestException $e) {
abort(400, $e->getMessage());
}
Outdated Package:
Service Registration:
dittto.custom_request will bypass validation.services.yaml:
tags: ['dittto.custom_request']
Request Object Mismatch:
Request object. In Laravel, manually pass the Illuminate\Http\Request.Request interface.Circular Dependencies:
Validation Short-Circuiting:
validate() returns false, the request stops processing.&&.Validation Failures:
validate():
public function validate() {
\Log::debug('Request data:', $this->request->all());
return $this->query->get('token') === 'allowed';
}
storage/logs/laravel.log) or Symfony’s var/log/dev.log.Service Not Found:
php bin/console debug:container App\Request\TestRequest
dd(app()->has('App\Request\TestRequest'));
Request Object Issues:
Request object matches the expected type (Symfony vs. Laravel).\Log::debug(get_class($this->request));
Reuse Validation Logic:
trait ValidatesToken {
public function validateToken()
{
return $this->query->get('token') === 'allowed';
}
}
Dynamic Validation:
class ApiKeyRequest extends CustomRequest {
public function __construct(Request $request, ApiKeyService $apiKeyService) {
$this->apiKeyService = $apiKeyService;
parent::__construct($request);
}
public function validate() {
$key = $this->header('X-API-KEY');
return $this->apiKeyService->isValid($key);
}
}
Performance:
public function validate() {
return cache()->remember("token_{$this->query->get('token')}", 3600, function() {
return $this->query->get('token') === 'allowed';
});
}
Testing:
$mockRequest = $this->createMock(CustomRequest::class);
$mockRequest->method('validate')->will
How can I help you explore Laravel packages today?