{"id":15168769,"url":"https://github.com/yiisoft/request-model","last_synced_at":"2025-10-01T02:30:59.953Z","repository":{"id":37091353,"uuid":"303347521","full_name":"yiisoft/request-model","owner":"yiisoft","description":null,"archived":true,"fork":false,"pushed_at":"2023-10-10T13:06:51.000Z","size":152,"stargazers_count":15,"open_issues_count":8,"forks_count":9,"subscribers_count":17,"default_branch":"master","last_synced_at":"2024-10-29T22:38:37.645Z","etag":null,"topics":["hacktoberfest","psr-7","request","validation","yii3"],"latest_commit_sha":null,"homepage":"https://www.yiiframework.com/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yiisoft.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"open_collective":"yiisoft","github":["yiisoft"]}},"created_at":"2020-10-12T09:49:54.000Z","updated_at":"2024-08-02T02:22:31.000Z","dependencies_parsed_at":"2023-12-13T03:35:01.354Z","dependency_job_id":"07b84438-43fc-4364-9a9c-ad9b79bc9aee","html_url":"https://github.com/yiisoft/request-model","commit_stats":{"total_commits":89,"total_committers":19,"mean_commits":4.684210526315789,"dds":0.8089887640449438,"last_synced_commit":"7e9b3c3a387d14af4d08436c13b6525cfa68cae5"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":"yiisoft/package-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiisoft%2Frequest-model","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiisoft%2Frequest-model/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiisoft%2Frequest-model/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiisoft%2Frequest-model/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yiisoft","download_url":"https://codeload.github.com/yiisoft/request-model/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234711822,"owners_count":18875340,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","psr-7","request","validation","yii3"],"created_at":"2024-09-27T06:41:42.526Z","updated_at":"2025-10-01T02:30:59.632Z","avatar_url":"https://github.com/yiisoft.png","language":"PHP","funding_links":["https://opencollective.com/yiisoft","https://github.com/sponsors/yiisoft"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cb\u003e\n        This package is deprecated. Use\n        \u003ca href=\"https://github.com/yiisoft/input-http\"\u003eYii Input HTTP\u003c/a\u003e instead.\n    \u003c/b\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    ❌\n\u003c/p\u003e\n\n---\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/yiisoft\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://yiisoft.github.io/docs/images/yii_logo.svg\" height=\"100px\"\u003e\n    \u003c/a\u003e\n    \u003ch1 align=\"center\"\u003eYii Request Model\u003c/h1\u003e\n    \u003cbr\u003e\n\u003c/p\u003e\n\n[![Latest Stable Version](https://poser.pugx.org/yiisoft/request-model/v/stable.png)](https://packagist.org/packages/yiisoft/request-model)\n[![Total Downloads](https://poser.pugx.org/yiisoft/request-model/downloads.png)](https://packagist.org/packages/yiisoft/request-model)\n[![Build status](https://github.com/yiisoft/request-model/workflows/build/badge.svg)](https://github.com/yiisoft/request-model/actions?query=workflow%3Abuild)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/yiisoft/request-model/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/yiisoft/request-model/?branch=master)\n[![Code Coverage](https://scrutinizer-ci.com/g/yiisoft/request-model/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/yiisoft/request-model/?branch=master)\n[![Mutation testing badge](https://img.shields.io/endpoint?style=flat\u0026url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fyiisoft%2Frequest-model%2Fmaster)](https://dashboard.stryker-mutator.io/reports/github.com/yiisoft/request-model/master)\n[![static analysis](https://github.com/yiisoft/request-model/workflows/static%20analysis/badge.svg)](https://github.com/yiisoft/request-model/actions?query=workflow%3A%22static+analysis%22)\n[![type-coverage](https://shepherd.dev/github/yiisoft/request-model/coverage.svg)](https://shepherd.dev/github/yiisoft/request-model)\n\nRequest model simplifies working with request data. It allows you to decorate data for easy retrieval and automatically\nvalidate it when needed.\n\n## Requirements\n\n- PHP 8.0 or higher.\n\n## Installation\n\nThe package could be installed with composer:\n\n```\ncomposer require yiisoft/request-model\n```\n\nAccording to [`yiisoft/middleware-dispatcher`](https://github.com/yiisoft/middleware-dispatcher) docs, you need to set\nthe implementation of `ParametersResolverInterface` to `HandlerParametersResolver` via container or pass directly.\n\n## General usage\n\n\nA simple version of the request model looks like the following:\n\n```php\nuse Yiisoft\\RequestModel\\RequestModel;\nuse Yiisoft\\Validator\\RulesProviderInterface;\nuse Yiisoft\\Validator\\Rule\\Email;\nuse Yiisoft\\Validator\\Rule\\Required;\n\nfinal class AuthRequest extends RequestModel implements RulesProviderInterface\n{\n    public function getLogin(): string\n    {\n        return (string)$this-\u003egetAttributeValue('body.login');\n    }\n\n    public function getPassword(): string\n    {\n        return (string)$this-\u003egetAttributeValue('body.password');\n    }\n\n    public function getRules(): array\n    {\n        return [\n            'body.login' =\u003e [\n                new Required(),\n                new Email(),\n            ],\n            'body.password' =\u003e [\n                new Required(),\n            ]\n        ];\n    }\n}\n```\n\nRoute:\n\n```php\n Route::post('/test')\n    -\u003eaction([SimpleController::class, 'action'])\n    -\u003ename('site/test')\n```\n\nUsage in controller:\n\n```php\nuse Psr\\Http\\Message\\ResponseInterface;\n\nfinal class SimpleController\n{\n    public function action(AuthRequest $request): ResponseInterface\n    {\n        echo $request-\u003egetLogin();\n        ...\n    }\n}\n```\n\nIf the data does not pass validation, `RequestValidationException` will be thrown.\nIf you need to handle an exception and, for example, send a response, you can intercept its middleware.\n\nFor example:\n\n```php\nfinal class ExceptionMiddleware implements MiddlewareInterface\n{\n    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface\n    {\n        try {\n            return $handler-\u003ehandle($request);\n        } catch (RequestValidationException $e) {\n            return new Response(400, [], $e-\u003egetFirstError());\n        }\n    }\n}\n```\n\nYou can use the request model without validation. To do this, you need to remove the `ValidatableModelInterface`.\nIn this case, the data will be included into the model, but will not be validated. For example:\n\n```php\nfinal class ViewPostRequest extends RequestModel\n{\n    public function getId(): int\n    {\n        return (int)$this-\u003egetAttributeValue('router.id');\n    }\n}\n```\n\nInside the request model class, data is available using the following keys:\n\n| key        | source                        |\n|------------|-------------------------------|\n| query      | $request-\u003egetQueryParams()    |\n| body       | $request-\u003egetParsedBody()     |\n| attributes | $request-\u003egetAttributes()     |\n| headers    | $request-\u003egetHeaders()        |\n| files      | $request-\u003egetUploadedFiles()  |\n| cookie     | $request-\u003egetCookieParams()   |\n| router     | $currentRoute-\u003egetArguments() |\n\nThis data can be obtained as follows \n\n```php\n$this-\u003erequestData['router']['id'];\n```\n\nor through the methods\n\n```php\n$this-\u003ehasAttribute('body.user_id');\n$this-\u003egetAttributeValue('body.user_id');\n```\n\n#### Attributes\n\nYou can use attributes in an action handler to get data from a request:\n\n```php\nuse Psr\\Http\\Message\\ResponseInterface;\nuse Yiisoft\\RequestModel\\Attribute\\Request;\nuse Yiisoft\\RequestModel\\Attribute\\Route;\n\nfinal class SimpleController\n{\n    public function action(#[Route('id')] int $id, #[Request('foo')] $attribute,): ResponseInterface\n    {\n        echo $id;\n        //...\n    }\n}\n```\n\nAttributes are also supported in closure actions.\n\nThere are several attributes out of the box:\n\n| Name          | Source                    |\n|---------------|---------------------------|\n| Body          | Parsed body of request    |\n| Query         | Query parameter of URI    |\n| Request       | Attribute of request      |\n| Route         | Argument of current route |\n| UploadedFiles | Uploaded files of request |\n\n### Unit testing\n\nThe package is tested with [PHPUnit](https://phpunit.de/). To run tests:\n\n```shell\n./vendor/bin/phpunit\n```\n\n### Mutation testing\n\nThe package tests are checked with [Infection](https://infection.github.io/) mutation framework. To run it:\n\n```shell\n./vendor/bin/infection\n```\n\n### Static analysis\n\nThe code is statically analyzed with [Psalm](https://psalm.dev/). To run static analysis:\n\n```shell\n./vendor/bin/psalm\n```\n\n### Support the project\n\n[![Open Collective](https://img.shields.io/badge/Open%20Collective-sponsor-7eadf1?logo=open%20collective\u0026logoColor=7eadf1\u0026labelColor=555555)](https://opencollective.com/yiisoft)\n\n### Follow updates\n\n[![Official website](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=flat)](https://www.yiiframework.com/)\n[![Twitter](https://img.shields.io/badge/twitter-follow-1DA1F2?logo=twitter\u0026logoColor=1DA1F2\u0026labelColor=555555?style=flat)](https://twitter.com/yiiframework)\n[![Telegram](https://img.shields.io/badge/telegram-join-1DA1F2?style=flat\u0026logo=telegram)](https://t.me/yii3en)\n[![Facebook](https://img.shields.io/badge/facebook-join-1DA1F2?style=flat\u0026logo=facebook\u0026logoColor=ffffff)](https://www.facebook.com/groups/yiitalk)\n[![Slack](https://img.shields.io/badge/slack-join-1DA1F2?style=flat\u0026logo=slack)](https://yiiframework.com/go/slack)\n\n## License\n\nThe Yii Request Model is free software. It is released under the terms of the BSD License.\nPlease see [`LICENSE`](./LICENSE.md) for more information.\n\nMaintained by [Yii Software](https://www.yiiframework.com/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyiisoft%2Frequest-model","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyiisoft%2Frequest-model","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyiisoft%2Frequest-model/lists"}