Category
stdlib · php-src-strict · spec refresh 2026-06-20
Problem
Two gaps in parse_str($encoded, $result) vs Zend:
1. Uninitialized by-ref $result (original scope)
Zend accepts an uninitialized variable passed by reference, allocates/populates the array. VM requires $result to already be an array (LogicException: argument #2 must be an array).
2. Return value — PHP 8+ void return (added 2026-06-20)
Since PHP 8.0, parse_str() returns null (void). VM returns true (ext/standard/parse_str.php sets $frame->returnVar->bool(true)).
Verified:
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php -r "parse_str(\"a=1\", \$out); var_export(\$out);"
php bin/vm.php -r "parse_str(\"a=1\", \$out); var_export(\$out);"
'
| Call |
Zend |
VM today |
parse_str('a=1', $out); var_export($out); |
array('a'=>'1') |
same array ✓ |
Return value of parse_str(...) |
null |
true ❌ |
Distinct from #4050 (one-arg form) and #4219 (third-arg prefix).
php-src reference
- php/php-src
ext/standard/basic_functions.c — PHP_FUNCTION(parse_str) / php_parse_str()
- By-ref
$result may be undefined; Zend creates the array in place
- PHP 8+: function return type
void (returns null in userland)
Repro
By-ref uninitialized:
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php test/repro-maintainer/parse_str_byref.php 2>&1
php bin/vm.php test/repro-maintainer/parse_str_byref.php 2>&1
'
| Call |
Zend PHP 8.x |
VM today |
parse_str('a=1&b=2', $result) (uninit $result) |
populated array |
LogicException ❌ |
Return value:
<?php
declare(strict_types=1);
$out = [];
var_export(parse_str('a=1', $out));
echo "\n";
var_export($out);
echo "\n";
Scope (this repo)
| Area |
Files |
| VM |
ext/standard/parse_str.php, VmParseStr.php — void return + uninit by-ref |
| JIT |
JitParseStr.php — write through by-ref slot when unset; no bool return |
| Tests |
test/compliance/cases/stdlib/parse_str_byref.phpt, parse_str_return_null.phpt |
PHP-in-PHP: #9295 routes JIT through VmHttp — VM semantics first.
Done when
Links
Category
stdlib· php-src-strict · spec refresh 2026-06-20Problem
Two gaps in
parse_str($encoded, $result)vs Zend:1. Uninitialized by-ref
$result(original scope)Zend accepts an uninitialized variable passed by reference, allocates/populates the array. VM requires
$resultto already be an array (LogicException: argument #2 must be an array).2. Return value — PHP 8+ void return (added 2026-06-20)
Since PHP 8.0,
parse_str()returnsnull(void). VM returnstrue(ext/standard/parse_str.phpsets$frame->returnVar->bool(true)).Verified:
parse_str('a=1', $out); var_export($out);array('a'=>'1')parse_str(...)nulltrue❌Distinct from #4050 (one-arg form) and #4219 (third-arg prefix).
php-src reference
ext/standard/basic_functions.c—PHP_FUNCTION(parse_str)/php_parse_str()$resultmay be undefined; Zend creates the array in placevoid(returnsnullin userland)Repro
By-ref uninitialized:
parse_str('a=1&b=2', $result)(uninit$result)LogicException❌Return value:
Scope (this repo)
ext/standard/parse_str.php,VmParseStr.php— void return + uninit by-refJitParseStr.php— write through by-ref slot when unset; no bool returntest/compliance/cases/stdlib/parse_str_byref.phpt,parse_str_return_null.phptPHP-in-PHP: #9295 routes JIT through
VmHttp— VM semantics first.Done when
parse_str()return isnull, nottrue./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter parse_str'greenLinks