parse_str
Parses a URL query string into an array of variables.
parse_str(string $string, array &$result): void- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$string | string | The URL-encoded query string to parse. |
$result | array | Passed by reference. Set to an array of key/value pairs extracted from the string. Mandatory as of PHP 8.0. |
Return value
voidNo value is returned; the parsed data is written into the result parameter.
Errors
Emits an E_WARNING and truncates the result when the number of variables exceeds the max_input_vars INI directive (default 1000).
Changelog
- PHP 8.0.0The result parameter is no longer optional — the function can no longer inject variables into the local scope.
- PHP 7.2.0Calling parse_str() without a second parameter emitted an E_DEPRECATED notice.
parse_str turns a query string such as page=2&sort=name&tags[]=php into a PHP array, applying URL decoding and rebuilding bracket notation into nested arrays. It is what PHP itself uses to populate $_GET, exposed so you can run it on a string you got from somewhere else — a stored redirect URL, a webhook payload, an OAuth callback you captured in a log.
Always pass the second argument
Before PHP 8.0 you could omit $result and the function would create variables in the current scope from user input — a serious security hole. That form was deprecated in 7.2 and removed in 8.0, so the two-argument call is now the only call. The variable you pass is overwritten wholesale, not merged into.
Key mangling
Because the keys were originally meant to become PHP variable names, spaces and dots in parameter names are converted to underscores: first name=Ada lands under first_name, and user.id under user_id. If your API uses dotted parameter names, parse_str will quietly rename them. Splitting the string yourself with explode and urldecode is the workaround.
Duplicate scalar keys collapse — the last one wins — and a bare key with no = becomes an empty string. The max_input_vars INI limit applies here too.
Example
When to use it
- Extract the parameters from a stored callback or redirect URL you did not receive as a live request.
- Parse a query string out of a webhook body or a log line for replay and debugging.
- Round-trip a URL: parse it, change one parameter, and rebuild it with http_build_query.
Frequently asked questions
Why is the second parameter of parse_str required now?
Because the one-argument form injected variables straight into the local scope from user-controlled input, which was an easy path to variable overwriting attacks. It was deprecated in PHP 7.2 and removed in PHP 8.0.
Why did parse_str change my parameter name?
Spaces and dots in keys are converted to underscores, a leftover from when the keys became PHP variable names. Parse the string manually with explode and urldecode if the exact key characters matter.
How do I turn an array back into a query string?
Use http_build_query($array). It is the direct counterpart to parse_str and handles nested arrays and URL encoding for you.
More examples
Editing one parameter in a URL
parse_url pulls out just the query portion, parse_str decodes it (note `php+8.5` becomes `php 8.5` — the plus is decoded to a space), and http_build_query re-encodes the modified array as `q=php+8.5&page=4&safe=1`. This pair is the reliable way to change a single parameter without string surgery.
<?php
$url = 'https://example.com/search?q=php+8.5&page=3&safe=1';
parse_str(parse_url($url, PHP_URL_QUERY), $params);
print_r($params);
$params['page'] = 4;
echo http_build_query($params), PHP_EOL;Duplicates, nesting and bare keys
`a` ends up as the string "2" — the second occurrence overwrote the first, so repeating a scalar key loses data unless you use `a[]=1&a[]=2`. `b` becomes a nested array with string keys x and y. The bare `c` with no equals sign becomes an empty string. Every value is a string, never an int.
<?php
parse_str('a=1&a=2&b[x]=9&b[y]=10&c', $out);
var_dump($out);
Discussion