Skip to content

Stdlib: strcoll()/strxfrm() locale collation parity #4376

Description

@PurHur

Category

stdlib

Status (expanded 2026-06-04 — implementation-ready)

Today: strcoll() and strxfrm() are not registered in ext/standard/Module.php (function_exists('strcoll') → false on VM). This is not a behavioral drift issue yet — the builtins are missing.

Problem

Zend implements locale-aware string collation via strcoll() and transformation via strxfrm(), honoring the active locale set by setlocale(LC_COLLATE, ...). PurHur/php-compiler must match Zend’s collation ordering and return types, including behavior under the default C locale.

This is a building block for locale-sensitive sorting behavior in userland and pairs with #3254 (setlocale()).

php-src reference

  • ext/standard/string.c — PHP_FUNCTION(strcoll), PHP_FUNCTION(strxfrm)
  • ext/standard/locale.c — locale handling and setlocale() plumbing

Repro (failure today)

test/compliance/cases/stdlib/strcoll_strxfrm_repro.php:

<?php
setlocale(LC_COLLATE, 'C');
var_dump(strcoll('a', 'b') < 0);
var_dump(strcoll('a', 'a') === 0);
var_dump(strcoll('b', 'a') > 0);
$out = strxfrm('hello');
var_dump(is_string($out));
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && cd /compiler && php bin/vm.php test/compliance/cases/stdlib/strcoll_strxfrm_repro.php'
Runtime Result
Zend three true, is_string true
VM (today) Call to undefined function strcoll()

Scope (this repo)

Area Path
New builtins ext/standard/strcoll.php, ext/standard/strxfrm.php
Registration ext/standard/Module.php
VM delegate to libc strcoll(3) / strxfrm(3) via thin wrapper (no new runtime/*.c logic)
JIT/AOT optional phase 2 — document VM-only in matrix if deferred
Tests test/compliance/cases/stdlib/strcoll_*.phpt

Done when

  • Repro runs on VM without undefined-function fatal; output matches Zend in php-compiler:22.04-dev
  • Invalid argument types throw Zend-like TypeError (see ext/standard/string.c)
  • script/capability-matrix.php lists both functions as VM yes
  • No permanent internal_* shims

Related

Activity

  1. added
    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 Jun 2, 2026
  2. PurHur commented on Jun 9, 2026

    @PurHur
    OwnerAuthor

    claim: PHP Compiler STD Lib — starting this run

  3. PurHur commented on Jun 9, 2026

    @PurHur
    OwnerAuthor

    Merged via #7743.

    Verification (green):

    • php bin/vm.php -r 'var_dump(strcoll("a","b")<0); echo strxfrm("hello"),"\n";' → bool(true) + hello
    • vendor/bin/phpunit --filter strcoll_strxfrm → VM + JIT compliance pass (5 tests)
    • vendor/bin/phpunit --filter strcoll_enum → enum TypeError pass
    • vendor/bin/phpunit test/unit/AotRegressionFixtureCatalogTest.php --filter strcoll_strxfrm → AOT compile-only pass
    • php bin/compile.php -l test/fixtures/aot/compile-only/strcoll_strxfrm.php → exit 0

    Implementation: VmLocaleCollate (libc FFI strcoll/strxfrm with strcmp/identity fallbacks); strcoll JIT lowers to libc like strcmp; strxfrm VM-only (JIT deferred). php-src ref: ext/standard/string.c.

  4. PurHur commented on Jun 10, 2026

    @PurHur
    OwnerAuthor

    Merged via #7861.

    Verification (Docker):

    • ./vendor/bin/phpunit --filter "strcoll_strxfrm|strxfrm" → OK (8 tests)
    • ./vendor/bin/phpunit --filter "AotTest.*strxfrm" → OK (1 test)
    • php bin/compile.php -l test/fixtures/aot/compile-only/strcoll_strxfrm.php → OK

    strxfrm() now lowers to libc strxfrm(3) two-pass sizing on JIT/AOT (php-src ext/standard/string.c); VM path unchanged via VmLocaleCollate.

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 machineimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-4:stdlibPhase 4 – stdlib for web apps

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions