Skip to content

Runtime: CLI / + ['argv'] (register_argc_argv) parity #4374

Closed

Description

@PurHur

Category

runtime

Problem

In CLI mode, Zend PHP populates $argc, $argv, and $_SERVER['argc']/$_SERVER['argv'] based on process arguments, gated by register_argc_argv (and with predictable shapes/types). PurHur/php-compiler should match Zend behavior, including when scripts are invoked with additional args and when register_argc_argv=0.

Verified gap (2026-06-03): even for bare -r snippets, $argv[0] differs (Standard input code vs Command line code). Multi-arg script invocations are not wired to real CLI args today.

php-src reference

Repro (failure today)

repro.php:

<?php
var_dump($argc, $argv);
var_dump($_SERVER['argc'] ?? null, $_SERVER['argv'] ?? null);
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
# Zend reference
php repro.php extra1 extra2

# This compiler (today)
php bin/vm.php repro.php extra1 extra2
# Also compare bare -r:
php -r "var_dump(\$argc, \$argv);"
php bin/vm.php -r "var_dump(\$argc, \$argv);"
'

Observed on master (Docker php-compiler:22.04-dev, 2026-06-03):

Check Zend PHP 8.2 bin/vm.php
php -r 'var_dump($argc,$argv);' $argc=int(1), $argv[0]="Standard input code" same shape but $argv[0]="Command line code"
$_SERVER['argc'] in -r present, mirrors $argc present, mirrors $argc
php repro.php a b $argc=3, argv includes script + a + b (worker: verify; often still 1-arg stub)

Second variant (after #4515 / VmIni exposes register_argc_argv):

php -d register_argc_argv=0 repro.php a
php bin/vm.php -d register_argc_argv=0 repro.php a
# Expect: no $argc/$argv (or empty per Zend SAPI rules)

Scope (this repo)

Done when

  • php bin/vm.php repro.php a b matches Zend: $argc === 3, $argv[0] is script path/basename, $argv[1]==='a', $argv[2]==='b'
  • $_SERVER['argv'] mirrors $argv when register_argc_argv=1
  • register_argc_argv=0 behavior matches Zend (no spurious argv pollution)
  • Compliance: test/compliance/cases/runtime/argv_cli.phpt

Links


Implementation notes (2026-06-03 backlog pass)

Committed repro

Add test/repro-maintainer/cli_argv_parity.php:

<?php
var_dump($argc, $argv);
var_dump($_SERVER['argc'] ?? null, $_SERVER['argv'] ?? null);

Native / AOT floor

Verification matrix

Command $argc $argv[1]
php test/repro-maintainer/cli_argv_parity.php a b 3 a
php bin/vm.php test/repro-maintainer/cli_argv_parity.php a b 3 a
php bin/jit.php test/repro-maintainer/cli_argv_parity.php a b 3 a
register_argc_argv=0 (see #4515) Zend rules same
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter cli_argv'
make bootstrap-selfhost-link

Done when (addendum)

  • -r snippet uses Standard input code for $argv[0] (match Zend 8.2), not Command line code
  • AOT-linked bin-compile-aot inherits forwarded argv for inventory driver

Activity

  1. added
    area:vmVirtual machine
    implementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claim
    MOST IMPORTANTThis are the most important targets
    on Jun 2, 2026
  2. PurHur commented on Jun 2, 2026

    @PurHur
    OwnerAuthor

    More concrete parity targets + references:

    php-src reference (more specific)

    • sapi/cli/php_cli.c: do_cli() / argv parsing and php_build_argv() hookup
    • main/php_variables.c: php_register_variable_ex() paths for $_SERVER population
    • INI: register_argc_argv in php.ini-development (behavior toggle)

    php-src tests to mirror

    • sapi/cli/tests/argv_001.phpt
    • sapi/cli/tests/argv_002.phpt
    • sapi/cli/tests/register_argc_argv_*.phpt

    Extra edge cases to include

    <?php
    // 1) script executed via relative vs absolute path
    // 2) arguments containing spaces / quotes should arrive as-is from the OS argv
    var_dump($argv);

    Done-when extension

    • $argv is an array with sequential integer keys starting at 0.
    • $_SERVER['argv'] matches $argv when enabled.
    • When disabled, $argc/$argv are unset or match Zend’s exact disabled behavior for this SAPI.
  3. PurHur commented on Jun 2, 2026

    @PurHur
    OwnerAuthor

    claim: lane-c-worker — starting this run

  4. PurHur commented on Jun 4, 2026

    @PurHur
    OwnerAuthor

    Implementation-ready addendum (2026-06-04 parity probe)

    Verified $argv wiring gap remains on master. Minimal repro:

    ./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
    php -r "var_dump(\$argc, \$argv[0] ?? null);"
    php bin/vm.php -r "var_dump(\$argc, \$argv[0] ?? null);"
    php bin/vm.php -r "var_dump(\$argc, \$argv[0] ?? null);" -- extra-arg
    '

    Expected Zend: $argv[0] is Command line code for -r snippets; additional CLI args after -- appear in $argv.

    Done-when checklist for workers:

    1. VM populates $argc/$argv without host PHP delegation
    2. $_SERVER['argc'] / $_SERVER['argv'] mirror $argc/$argv when register_argc_argv=1
    3. register_argc_argv=0 hides $argc/$argv like Zend
    4. Delete C argv table via php-in-php: native CLI argv/globals bootstrap — delete phpc_cli_argv.c (~182 lines), pairs #4374 #5407 once PHP path lands (~182 lines from phpc_cli_argv.c)

    php-src: sapi/cli/php_cli.c, main/php_variables.c

  5. PurHur commented on Jun 4, 2026

    @PurHur
    OwnerAuthor

    claim: cursor-agent-lane-c — continuing #4374 (Standard input code + -- separator); PR incoming.

  6. PurHur commented on Jun 4, 2026

    @PurHur
    OwnerAuthor

    Merged #5880

    Verification: php bin/vm.php -r now matches Zend 8.2 (Standard input code, -- stripped before user args); script invocation with extra args unchanged; vendor/bin/phpunit test/compliance/ --filter cli_argv OK.

    Follow-up: register_argc_argv=0 still blocked on -d INI forwarding (#4515).

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

    MOST IMPORTANTThis are the most important targetsarea:vmVirtual machineimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-1:web-runtimePhase 1 – CGI/web runtime

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions