Repository navigation
Closed
Labels
area:vmVirtual machineVirtual machineenhancementNew feature or requestNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimSpec complete: repro, php-src ref, done-when — safe for workers to claimphase-4:stdlibPhase 4 – stdlib for web appsPhase 4 – stdlib for web apps
Description
Category
stdlib · php-src-strict · spec refresh 2026-06-20
Problem
Zend internal functions with string parameters coerce int/float/bool to string in weak mode (default). This compiler often throws LogicException instead, or rejects valid calls that Zend accepts.
Closed #3549 fixed str_contains/strpos; putenv(), getenv(), and several stream helpers still diverge.
php-src reference
- php/php-src
ext/standard/basic_functions.c—PHP_FUNCTION(putenv),PHP_FUNCTION(getenv)→_convert_to_string()on assignment/lookup - php/php-src
Zend/zend_API.c—zend_parse_parametersZ_PARAM_STRcoercion - php/php-src
ext/standard/streams.c—PHP_FUNCTION(fread)string length coercion
Repro (failure today)
<?php
putenv(123);
echo getenv('123') === '123' ? "ok\n" : "bad\n";
$f = fopen('php://memory', 'r+');
fwrite($f, 'x');
rewind($f);
echo fread($f, 2), "\n";./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php repro.php
php bin/vm.php repro.php 2>&1
'| Call | Zend PHP 8.2 | VM today |
|---|---|---|
putenv(123) |
true (sets "123") |
LogicException ❌ |
getenv(123) |
looks up "123" |
error / wrong ❌ |
fread($f, 2) after write |
'x' (length int ok) |
verify — may LogicException ❌ |
With declare(strict_types=1); in user code, Zend still coerces internal function args — repro both modes.
Scope (this repo)
| Layer | Path |
|---|---|
| Shared helper | ext/standard/VmString.php — coerceStringBuiltinArg() / coerceOperand() for Z_PARAM_STR |
| VM | ext/standard/putenv_.php, getenv_.php, ext/standard/fread.php (and siblings from #4177 batch) |
| JIT | ext/standard/JitEnv.php, JitFread.php — runtime coercion when operand not compile-time literal |
| Tests | test/compliance/cases/stdlib/internal_string_param_coercion.phpt |
| Matrix | script/capability-matrix.php notes |
PHP-in-PHP: coercion in ext/standard/; no new runtime/*.c string tables.
Out of scope (separate issues)
- Enum case operands → TypeError (see Stdlib: str_contains()/str_starts_with()/str_ends_with()/strcmp()/strcoll() — enum case operands must TypeError (ext/standard/string.c) #8825, Stdlib: builtin wrong-type parameters — TypeError not LogicException (ext/standard parity) #4178)
resource/arrayoperands → TypeError like Zend
Done when
- Repro prints
ok+xon VM - Invalid types (array/object) throw
TypeError, notLogicException - JIT
putenv(123)/fread($f, $n)match VM when lowered -
./script/ci-fast.sh --filter internal_string_param_coerciongreen
Verification
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter internal_string_param_coercion'Related
- Stdlib: internal string function numeric coercion — strpos/str_contains vs strlen (ext/standard/string.c parity) #3549 (closed) · Stdlib: nl2br() — scalar-to-string and bool coercion for $use_xhtml (ext/standard/string.c parity) #4293 nl2br · Stdlib: preg_quote() / quotemeta() — scalar-to-string coercion (ext/standard/string.c parity) #4294 preg_quote · Stdlib: builtin wrong-type parameters — TypeError not LogicException (ext/standard parity) #4178 enum batch · Epic: Self-host critical path — compiler compiles itself (M3→M5) #1492
Metadata
Metadata
Assignees
Labels
area:vmVirtual machineVirtual machineenhancementNew feature or requestNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimSpec complete: repro, php-src ref, done-when — safe for workers to claimphase-4:stdlibPhase 4 – stdlib for web appsPhase 4 – stdlib for web apps
Activity
PurHur commentedon Jun 9, 2026
claim: PHP Compiler STD Lib — starting this run
PurHur commentedon Jun 9, 2026
Unclaiming: putenv(123) and getenv(123) already coerce scalars via coerceStringBuiltinArg/JitStringBuiltinArg on master. Both return true/'abc' in Docker repro. Issue repro getenv after putenv(123) also fails on Zend (unset semantics). Picking a different issue.
PurHur commentedon Jul 17, 2026
claim: worker-lane-b — starting this run
Pillar 1 (this workspace):
php script/bootstrap-inventory.php --check./script/release-readiness.sh --jsongetenv(999001)coerces; VM TypeErrorImplementing getenv/putenv scalar→string coercion (php-src-strict).
Stdlib: getenv() scalar name coercion without strict_types (#4177) (#…
PurHur commentedon Jul 17, 2026
Merged #20281
Fix
getenv()now uses caller-strict_types-aware Z_PARAM_STR_OR_NULL coercion (typedNullableStringBuiltinArgForFrame/lowerStrictOrCoercible) so weak-modegetenv(1)matches Zend whiledeclare(strict_types=1)still TypeErrors (#17765).Verification
putenv()/fread()were already green on master for this issue’s repro.