PHP limits the nesting depth of input variables. A query string with too many bracket levels can make parse_str() emit a warning and discard data. If a framework converts warnings to exceptions, an untrusted URL can become a 500 response. Treat it as invalid client input and return 400.
Last updated: October 8, 2026.
<?php
declare(strict_types=1);
function parseQuerySafely(string $query): array
{
if (strlen($query) > 8192) {
throw new InvalidArgumentException('Query string is too long.');
}
set_error_handler(
static function (int $level, string $message): never {
throw new ErrorException($message, 0, $level);
}
);
try {
parse_str($query, $values);
return $values;
} catch (ErrorException $error) {
throw new InvalidArgumentException('Invalid query string.', 0, $error);
} finally {
restore_error_handler();
}
}
try {
$query = parseQuerySafely($_SERVER['QUERY_STRING'] ?? '');
} catch (InvalidArgumentException) {
http_response_code(400);
exit('Bad Request');
}Install this behavior at the HTTP boundary before session, routing, or logging middleware repeatedly normalizes the same malformed URL. Keep detailed diagnostics in server logs, but return a short generic response to the client.
Keep defensive PHP input limits enabled
The default max_input_nesting_level is 64 and controls nesting in input variables. Raising it globally to accommodate arbitrary hostile requests increases parsing work and usually hides the real problem. Define the shape and maximum depth that the application accepts instead.
The PHP manual lists max_input_nesting_level with the other input-processing directives. The parse_str() reference also notes that parsing is subject to input limits and that excess input can raise warnings or be omitted.
Apply limits at more than one layer
Configure a reasonable request-target limit in the web server or proxy, then validate individual parameter count, name length, value length, and array depth in the application. A URL-length limit alone does not guarantee shallow data, and a nesting limit alone does not prevent thousands of flat parameters.
Do not suppress the warning and continue with a partial parameter array. A missing authorization or filtering value can change application behavior. Return 400, attach a request identifier to the log, and rate-limit repeated malformed requests. Continue with reading the current PHP URL, working with PHP arrays, and debugging PHP with Xdebug.