Description
- Laravel Version: 9.12.2
- PHP Version: PHP 8.1.4 (cli) (built: Mar 16 2022 09:33:31) (ZTS Visual C++ 2019 x64)
- Database Driver & Version: MySql 8.0.16
Description:
I have an api POST route with json contents. Very unexpected this route was giving Allowed memory size of 134217728 bytes exhausted (tried to allocate ... bytes) errors.
To debug this issue:
- I adjusted public/index.php so the request would run to the end and would not be aborted by memory exhausted errors.
ini_set("memory_limit", "-1");
-
I attached XDEBUG in profile mode.
-
I replayed the request.
-
I used QCacheGrind to visualize the profile:
As the profile shows, Illuminate\Http\Request::createFromBase
via Request->json()
calls json_decode()
twice. Which is unwanted, because I don't use the Request::json()
to retrieve the json contents. I do my own json_decode((string) Request::getContents())
.
I did some digging in the Laravel History and found the commit introducing the json_decode behaviour in [9.x]: 13e4a7f The commit message states: ... This commit solves the underlying issue without breaking compatibility with the original functionality. ...
This commit is breaking compatibility, because it does not take memory consumption into account. Neither does it take performance into account, decoding the same request body twice is performance degradation. For large JSON (in my case Content-Length: 6428178) this can easily lead to memory exhausted errors. In Laravel 7.x there was no memory exhausted error.