Skip to content

Regression: str_replace()/str_ireplace(null $search) still coerce under PROFILE=8.4 (ext/standard/string.c) #20173

Closed

Description

@PurHur

Category

stdlib · php-src-strict · PHP 8.4 null→TypeError · ext/standard

Problem

Under PHP_COMPILER_PROFILE=8.4, str_replace(null, $replace, $subject) / str_ireplace(null, …) still coerce $search to '' and return $subject unchanged. $subject null already TypeErrors; $search must too. php-src 8.4 rejects null for non-nullable array|string search args with TypeError.

Repro (PROFILE=8.4) php-src 8.4 VM (2026-07-17)
str_replace(null, 'b', 'hay') TypeError 'hay'
str_ireplace(null, 'b', 'Hay') TypeError 'Hay'
str_replace('a', 'b', null) TypeError TypeError (already OK)

php-src reference

  • php/php-src ext/standard/string.c — php_str_replace_common / Z_PARAM_ARRAY_OR_STR for $search
  • PHP 8.4 forward: null to non-nullable internal string/array args → TypeError

PHP implementation target

  • ext/standard/ str_replace / str_ireplace builtins (VM + JIT helpers)
  • Reuse shared 8.4 null guard (VmString::coerceZparamStrBuiltinArg / array-or-string variant) for $search — PHP-in-PHP only, no new C

Repro

./script/docker-exec.sh -- bash -lc 'cat > /tmp/str_replace_null84.php <<'"'"'PHP'"'"'
<?php
foreach (["str_replace" => fn() => str_replace(null, "b", "hay"), "str_ireplace" => fn() => str_ireplace(null, "b", "Hay")] as $n => $fn) {
  try { echo "$n COERCED ", var_export($fn(), true), "\n"; }
  catch (Throwable $e) { echo "$n ", get_class($e), "\n"; }
}
PHP
PHP_COMPILER_PROFILE=8.4 php bin/vm.php /tmp/str_replace_null84.php'

Expected: both TypeError. Today: COERCED 'hay' / COERCED 'Hay'.

Done when

  • str_replace(null, …) / str_ireplace(null, …) throw TypeError under PHP_COMPILER_PROFILE=8.4 on VM
  • JIT/AOT agree when in scope
  • Compliance .phpt under test/compliance/cases/string/
  • Default/8.2 profile still coerces like Zend 8.2
  • php-src-strict; no php-compiler-strict shortcut

Activity

  1. added
    bugSomething isn't working
    phase-4:stdlibPhase 4 – stdlib for web apps
    area:vmVirtual machine
    implementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claim
    on Jul 17, 2026
  2. PurHur commented on Jul 18, 2026

    @PurHur
    OwnerAuthor

    claim: PHP Compiler STD Lib — starting this run

    Trust probe (this workspace):

    Implementing str_replace/str_ireplace null $search → TypeError under PROFILE=8.4.

  3. PurHur commented on Jul 18, 2026

    @PurHur
    OwnerAuthor

    Merged via #20508

    Under PHP_COMPILER_PROFILE=8.4, str_replace(null, …) / str_ireplace(null, …) TypeError on $search/$replace (shared Z_PARAM_STR_OR_ARR guard with subject). Default profile still deprecates+coerces.

    Verified: VM + JIT compliance + AOT fixtures (bin/compile.php exit 255 with TypeError).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:vmVirtual machinebugSomething isn't workingimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-4:stdlibPhase 4 – stdlib for web appsstdlib

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions