Skip to content

Stdlib: ReflectionClass::getMethods() — filter flags + inheritance/visibility parity (ext/reflection/php_reflection.c) #4480

Description

@PurHur

Category

stdlib · php-src-strict · spec refresh 2026-06-20

Problem

ReflectionClass::getMethods(?int $filter = null): array returns incorrect method sets vs Zend/php-src:

  • inheritance rules (parent private methods must not appear on child ReflectionClass)
  • visibility filtering (ReflectionMethod::IS_PUBLIC / IS_PROTECTED / IS_PRIVATE)
  • IS_STATIC, IS_ABSTRACT, IS_FINAL filter flags
  • declaring class correctness (ReflectionMethod::getDeclaringClass())

Blocks PHPUnit-style runners, DI containers, and self-host reflection tooling.

Focused sub-issue: parent-private leak tracked as #7191 (implement first or together).

php-src reference

Repro (failure today — verified 2026-06-20)

test/repro-maintainer/reflection_class_get_methods.php:

<?php
declare(strict_types=1);

class A {
    public function pubA(): void {}
    protected function protA(): void {}
    private function privA(): void {}
    public static function statA(): void {}
}
class B extends A {
    public function pubB(): void {}
    private function privB(): void {}
}

$r = new ReflectionClass(B::class);
foreach ($r->getMethods() as $m) {
    echo $m->getDeclaringClass()->getName(), '::', $m->getName(), "\n";
}
echo "--- public only ---\n";
foreach ($r->getMethods(ReflectionMethod::IS_PUBLIC) as $m) {
    echo $m->getDeclaringClass()->getName(), '::', $m->getName(), "\n";
}
echo "--- static only ---\n";
foreach ($r->getMethods(ReflectionMethod::IS_STATIC) as $m) {
    echo $m->getDeclaringClass()->getName(), '::', $m->getName(), "\n";
}
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php test/repro-maintainer/reflection_class_get_methods.php > /tmp/zend.txt
php bin/vm.php test/repro-maintainer/reflection_class_get_methods.php > /tmp/vm.txt
diff -u /tmp/zend.txt /tmp/vm.txt | head -40
'

Expected (Zend PHP 8.2+)

Section Method lines (sorted)
Unfiltered A::protA, A::pubA, A::statA, B::pubB — exclude A::privA, B::privB
IS_PUBLIC A::pubA, A::statA, B::pubB
IS_STATIC A::statA

Actual (bin/vm.php, 2026-06-20)

  • Unfiltered includes A::privA and B::privB (private leak)
  • Filter bitmasks likely wrong until inheritance walk fixed

Scope (this repo)

Layer Path
VM metadata ext/standard/VmReflection.php — walk ClassEntry method tables + inheritance
Builtin classes lib/VM/BuiltinClasses.php — ReflectionMethod materialization
Compiler export class/method tables from declare opcodes
Tests port ReflectionClass_getMethods_001.phpt subset + #7191 private-leak PHPT

PHP-in-PHP: reflection tables in lib/ + ext/standard; no new runtime/*.c.

Done when (php-src-strict)

Related

Activity

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