phpsoftbox / request
Request component for the PhpSoftBox framework
Requires
- php: ^8.4
- phpsoftbox/validator: dev-master
- psr/http-message: ^2.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.93
- phpsoftbox/cli-app: dev-master
- phpsoftbox/cs-fixer: ^1.1.0
- phpsoftbox/http-message: dev-master
- phpunit/phpunit: ^11.2
This package is auto-updated.
Last update: 2026-06-17 06:20:11 UTC
README
About
phpsoftbox/request — тонкая оболочка над PSR‑7 запросом с удобными методами доступа к данным и встроенной валидацией через phpsoftbox/validator.
Ключевые возможности:
- единый доступ к query/body/cookies/files/attributes;
- валидация через
Request::validate(),RequestSchemaиApiSchema; - доступ к оригинальному PSR‑7 запросу через
psr().
Quick Start
use PhpSoftBox\Request\Request; use PhpSoftBox\Validator\Validator; $request = new Request($psrRequest, new Validator()); $data = $request->validate([ 'email' => [ new \PhpSoftBox\Validator\Rule\PresentValidation(), new \PhpSoftBox\Validator\Rule\FilledValidation(), (new \PhpSoftBox\Validator\Rule\StringValidation())->email(), ], ]);
RequestSchema
Если удобнее держать правила в классе:
use PhpSoftBox\Request\RequestSchema; use PhpSoftBox\Validator\Rule\FilledValidation; use PhpSoftBox\Validator\Rule\PresentValidation; use PhpSoftBox\Validator\Rule\StringValidation; final class LoginRequest extends RequestSchema { public function rules(): array { return [ 'login' => [new PresentValidation(), new FilledValidation(), new StringValidation()], 'password' => [new PresentValidation(), new FilledValidation(), new StringValidation()], ]; } }
Далее в контроллере:
$schema = new LoginRequest($request); $data = $schema->validate();
Внутри RequestSchema можно читать параметры текущего маршрута через helper route():
$this->route()->has('param')— проверит, передан ли route-параметр;$this->route()->get('param', $default)— вернет route-параметр или default;$this->route()->require('param')— вернет route-параметр или выброситMissingRouteParameterException;$this->route()->entity('param', Entity::class)— вернет resolved entity или выброситUnexpectedRouteParameterException;$this->route()->entityOrNull('param', Entity::class)— вернет resolved entity или null, если route-параметра нет;$this->route()->key('param')— вернет обязательный route key какint|string.
entity() нужен, когда схема зависит от текущего route-ресурса:
if ($this->route()->has('product')) { $product = $this->route()->entity('product', Product::class); if ($product->archived) { // rules for archived product update } }
key() принимает сырой route key или resolved entity. Для entity класс проверяется через
instanceof, а ключ берется через явный extractor. Если entity реализует ORM
EntityInterface, extractor можно не передавать: будет использован id().
final class ShipmentProductsRequest extends RequestSchema { public function rules(): array { return [ 'product_ids' => [ ExistsValidation::make() ->table('shipment_products') ->column('product_id') ->where('shipment_id', $this->route()->key('shipment', Shipment::class)) ->all(), ], ]; } }
Для кастомного объекта или нестандартного ключа передайте extractor. Если route-параметр остался сырым scalar key, extractor не вызывается:
$this->route()->key('shipment', Shipment::class, static fn (Shipment $shipment): int => $shipment->id()); $this->route()->key('product');
PhpStorm meta
Если PhpStorm не выводит тип entity() / entityOrNull() из PHPDoc @template,
можно добавить в корень проекта .phpstorm.meta.php:
<?php namespace PHPSTORM_META { override(\PhpSoftBox\Request\RouteParameters::entity(1), map([ '' => '@', ])); override(\PhpSoftBox\Request\RouteParameters::entityOrNull(1), map([ '' => '@|null', ])); }
Индекс 1 указывает на второй аргумент метода: Product::class в вызове
entity('product', Product::class). После этого IDE должна понимать:
$product = $this->route()->entity('product', Product::class); // Product $product = $this->route()->entityOrNull('product', Product::class); // Product|null
Для key() такой override не нужен: метод возвращает int|string. Если ключ
извлекается из entity, тип entity задается в extractor:
$productId = $this->route()->key( 'product', Product::class, static fn (Product $product): int => $product->id(), );
ApiSchema
Для валидации входящих payload без HTTP-request:
use PhpSoftBox\Request\ApiSchema; final class MarketplaceCardSchema extends ApiSchema { public function rules(): array { return [ 'id' => [new \PhpSoftBox\Validator\Rule\PresentValidation(), new \PhpSoftBox\Validator\Rule\IntValidation()], ]; } } $schema = new MarketplaceCardSchema($payload); $data = $schema->validate();
Schema Definition
RequestSchema и ApiSchema поддерживают композицию правил через InputSchemaDefinition.
Схему можно расширять, заменять или сужать перед валидацией:
use PhpSoftBox\Request\InputSchemaDefinition; $schema = (new TaskTransitionRequest($request)) ->merge(InputSchemaDefinition::make( rules: ['acceptance_data.driver_name' => [new StringValidation()->nullable()]], filters: ['acceptance_data.driver_name' => [new TrimFilter(), new NullIfEmptyFilter()]], )) ->only(['acceptance_data.driver_name']); $data = $schema->validate();
Для переиспользуемых частей схемы можно реализовать InputSchemaPartInterface.