{"action":"created","issue":{"url":"https://api.github.com/repos/symfony/symfony/issues/29059","repository_url":"https://api.github.com/repos/symfony/symfony","labels_url":"https://api.github.com/repos/symfony/symfony/issues/29059/labels{/name}","comments_url":"https://api.github.com/repos/symfony/symfony/issues/29059/comments","events_url":"https://api.github.com/repos/symfony/symfony/issues/29059/events","html_url":"https://github.com/symfony/symfony/issues/29059","id":376712112,"node_id":"MDU6SXNzdWUzNzY3MTIxMTI=","number":29059,"title":"[HttpKernel] Extending the Request class","user":{"login":"andreaslarssen","id":3169836,"node_id":"MDQ6VXNlcjMxNjk4MzY=","avatar_url":"https://avatars0.githubusercontent.com/u/3169836?v=4","gravatar_id":"","url":"https://api.github.com/users/andreaslarssen","html_url":"https://github.com/andreaslarssen","followers_url":"https://api.github.com/users/andreaslarssen/followers","following_url":"https://api.github.com/users/andreaslarssen/following{/other_user}","gists_url":"https://api.github.com/users/andreaslarssen/gists{/gist_id}","starred_url":"https://api.github.com/users/andreaslarssen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andreaslarssen/subscriptions","organizations_url":"https://api.github.com/users/andreaslarssen/orgs","repos_url":"https://api.github.com/users/andreaslarssen/repos","events_url":"https://api.github.com/users/andreaslarssen/events{/privacy}","received_events_url":"https://api.github.com/users/andreaslarssen/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-11-02T08:26:43Z","updated_at":"2018-11-02T11:01:51Z","closed_at":null,"author_association":"NONE","body":"I'm on symfony/framework-bundle 4.1.6 which requires symfony/http-kernel ^4.1 (and symfony/http-foundation ^4.1).\r\n\r\nI wanted to extend the Symfony\\Component\\HttpFoundation\\Request class, and started googling it, and found very little on the subject. I started reading the docs, and on the [http-kernel](https://symfony.com/doc/current/components/http_kernel.html#component-http-kernel-kernel-request) page, there's a gray info box on getting the controller arguments (...in the symfony framework). The second bullet in the box reads: \r\n\r\n> \"2. If the argument in the controller is type-hinted with Symfony's Request object, the Request is passed in as the value. If you have a custom Request class, it will be injected as long as you extend the Symfony Request.\"\r\n\r\nSo I created a custom Request class, extending the HttpFoundation Request class:\r\n\r\n```php\r\nnamespace App\\Requests;\r\n\r\nuse Symfony\\Component\\HttpFoundation\\Request;\r\n\r\nclass MyCustomRequest extends Request {}\r\n```\r\n\r\nI injected the new custom Request into my controller:\r\n\r\n```php\r\nnamespace App\\Controller;\r\n\r\nuse App\\Requests\\MyCustomRequest;\r\n\r\npublic function postSomething(MyCustomRequest $request) {\r\n\r\n}\r\n```\r\n\r\nThen my app crashed, saying that:\r\n\r\n```\r\nArgument 1 passed to App\\Controller\\MyController::postSomething() must be an instance of App\\Requests\\MyCustomRequest, instance of Symfony\\Component\\HttpFoundation\\Request given, called in /var/www/symfony/vendor/symfony/http-kernel/HttpKernel.php on line 149.\r\n```\r\n\r\nI debugged my way to the RequestValueResolver class:\r\n\r\n```php\r\nnamespace Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver;\r\n\r\nfinal class RequestValueResolver implements ArgumentValueResolverInterface\r\n{\r\n    /**\r\n     * {@inheritdoc}\r\n     */\r\n    public function supports(Request $request, ArgumentMetadata $argument)\r\n    {\r\n        return Request::class === $argument->getType() || is_subclass_of($argument->getType(), Request::class);\r\n    }\r\n\r\n    /**\r\n     * {@inheritdoc}\r\n     */\r\n    public function resolve(Request $request, ArgumentMetadata $argument)\r\n    {\r\n        yield $request;\r\n    }\r\n}\r\n```\r\n\r\n...and when the request hits the supports method, the argument type is MyCustomRequest class, the $request is the HttpFoundation\\Request, and the is_subclass_of test returns true.\r\n\r\nWhen the request hits the resolve method, the argument type is still MyCustomRequest, the $request is still the HttpFoundation\\Request, but the method returns (yields) the HttpFoundation\\Request, which ends up injecting the HttpFoundation\\Request class, and not MyCustomRequest, into my controller.\r\n\r\nFor now, I've added a custom RequestValueResolver, and changed it to this:\r\n\r\n```php\r\nclass RequestValueResolver implements ArgumentValueResolverInterface {\r\n  /**\r\n   * {@inheritdoc}\r\n   */\r\n  public function supports(Request $request, ArgumentMetadata $argument) {\r\n      return is_subclass_of($argument->getType(), Request::class);\r\n   }\r\n\r\n  /**\r\n   * {@inheritdoc}\r\n   */\r\n  public function resolve(Request $request, ArgumentMetadata $argument) {\r\n    $requestClass = $argument->getType();\r\n\r\n    yield forward_static_call([$requestClass, 'createFromGlobals']);\r\n  }\r\n}\r\n```\r\n\r\n...which injects the correct Request class. Is it the right thing to do? No idea.\r\n\r\nIf I'm reading the docs or the code wrong, or if there's another way to do this, let me know. If not, this just might be a surprising bug as noone have reported it yet. "},"comment":{"url":"https://api.github.com/repos/symfony/symfony/issues/comments/435343797","html_url":"https://github.com/symfony/symfony/issues/29059#issuecomment-435343797","issue_url":"https://api.github.com/repos/symfony/symfony/issues/29059","id":435343797,"node_id":"MDEyOklzc3VlQ29tbWVudDQzNTM0Mzc5Nw==","user":{"login":"andreaslarssen","id":3169836,"node_id":"MDQ6VXNlcjMxNjk4MzY=","avatar_url":"https://avatars0.githubusercontent.com/u/3169836?v=4","gravatar_id":"","url":"https://api.github.com/users/andreaslarssen","html_url":"https://github.com/andreaslarssen","followers_url":"https://api.github.com/users/andreaslarssen/followers","following_url":"https://api.github.com/users/andreaslarssen/following{/other_user}","gists_url":"https://api.github.com/users/andreaslarssen/gists{/gist_id}","starred_url":"https://api.github.com/users/andreaslarssen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andreaslarssen/subscriptions","organizations_url":"https://api.github.com/users/andreaslarssen/orgs","repos_url":"https://api.github.com/users/andreaslarssen/repos","events_url":"https://api.github.com/users/andreaslarssen/events{/privacy}","received_events_url":"https://api.github.com/users/andreaslarssen/received_events","type":"User","site_admin":false},"created_at":"2018-11-02T11:01:51Z","updated_at":"2018-11-02T11:01:51Z","author_association":"NONE","body":"I might have misunderstood this completely, and confused the request value resolver with the actual request on the request stack. \r\n\r\nI think I'll use the paramconverter and turn the request content into a entity instead. \r\n\r\nBut just out of curiosity; If one would like to dynamically override the Request class, how would one do that? Use the event cycle to swap the request? Or should you just never override it?\r\n\r\nEditing index.php (a framework specific file) don't seem like a good idea"}}
{"actor":{"display_login":"andreaslarssen"}}