Category
Language · php-src-strict · call/operand temps · print_r return
Problem
When print_r($value, true) is used directly as an argument to another call, the VM remaps the next string-literal argument onto the same temporary as the print_r return. Observable effect: str_contains / strpos / str_starts_with / str_ends_with / strstr behave as if the needle were a copy of the haystack (always a hit). Assigning the print_r result to a local first is fine; a variable needle is fine.
Probed 2026-07-28 vs Zend 8.2.32.
| Repro |
Zend |
VM |
str_contains(print_r([1,2,3], true), 'zzz') |
false |
true |
str_contains(print_r([1,2,3], true), $n='zzz') |
false |
false |
$s=print_r([1,2,3], true); str_contains($s,'zzz') |
false |
false |
wrapper sc(print_r([1], true), 'zzz') seeing needle |
'zzz' (len 3) |
needle === haystack print_r string (len 23) |
strpos(print_r([1,2,3], true), 'zzz') |
false |
0 |
str_starts_with(print_r([1,2,3], true), 'zzz') |
false |
true |
php-src reference
PHP implementation target
Repro
./script/docker-exec.sh -- bash -lc 'php bin/vm.php -r '\''
var_export(str_contains(print_r([1,2,3], true), "zzz"));
echo "\n";
$n = "zzz";
var_export(str_contains(print_r([1,2,3], true), $n));
echo "\n";
'\'''
Expect: false / false. Actual: true / false.
Done when
Maintainer gate note (2026-07-28)
Pillar 1: user_release_ready: yes; north-star5-fast ok; inventory 6614/6614 inside readiness; host bootstrap-inventory --check still reports committed docs/bootstrap-inventory.md construct-flag drift for HelperRuntimeCache.php. Gen-0 provenance stale (known).
Category
Language· php-src-strict · call/operand temps ·print_rreturnProblem
When
print_r($value, true)is used directly as an argument to another call, the VM remaps the next string-literal argument onto the same temporary as theprint_rreturn. Observable effect:str_contains/strpos/str_starts_with/str_ends_with/strstrbehave as if the needle were a copy of the haystack (always a hit). Assigning theprint_rresult to a local first is fine; a variable needle is fine.Probed 2026-07-28 vs Zend 8.2.32.
str_contains(print_r([1,2,3], true), 'zzz')falsetruestr_contains(print_r([1,2,3], true), $n='zzz')falsefalse$s=print_r([1,2,3], true); str_contains($s,'zzz')falsefalsesc(print_r([1], true), 'zzz')seeing needle'zzz'(len 3)strpos(print_r([1,2,3], true), 'zzz')false0str_starts_with(print_r([1,2,3], true), 'zzz')falsetruephp-src reference
ext/standard/basic_functions.stub.php—print_rPHP implementation target
lib/Compiler.php/ call lowering — ARG_SEND / temp lifetime for builtin return used as call arg (peer: UnhandledMatchError subject snapshot Regression: UnhandledMatchError message always NULL for variable subjects — Zend formats value (re-#23664, Zend/zend_exceptions.c) #24329)ext/standardprint_rlowering only if it uniquely fails to materialize a fresh return temp; prefer shared call-arg fixruntime/Repro
Expect:
false/false. Actual:true/false.Done when
print_r(..., true)as haystack with literal needle matches Zend forstr_contains/strpos/str_*_with/strstrtest/compliance/cases/; php-src-strict; no php-compiler-strict shortcutMaintainer gate note (2026-07-28)
Pillar 1:
user_release_ready: yes;north-star5-fastok; inventory6614/6614inside readiness; hostbootstrap-inventory --checkstill reports committeddocs/bootstrap-inventory.mdconstruct-flag drift forHelperRuntimeCache.php. Gen-0 provenance stale (known).