Skip to content
Reflection
step 1/5

Reading — step 1 of 5

Learn

~1 min readReflection and Attributes

PHP's Reflection* classes inspect code at runtime. Used by frameworks for routing, dependency injection, validation.

<?php
class User {
    public function __construct(
        public readonly string $name,
        public readonly int $age,
    ) {}

    public function greet(string $other): string {
        return "Hi {$other}, I'm {$this->name}";
    }
}

$rc = new ReflectionClass(User::class);

echo $rc->getName();                          // "User"
foreach ($rc->getProperties() as $prop) {
    echo $prop->getName() . ": " . $prop->getType() . "\n";
}
foreach ($rc->getMethods() as $method) {
    echo $method->getName() . "(";
    foreach ($method->getParameters() as $p) {
        echo $p->getType() . " " . $p->getName() . ", ";
    }
    echo ")\n";
}

ReflectionMethod for invocation:

$user = new User('Ada', 36);
$method = $rc->getMethod('greet');
echo $method->invoke($user, 'Bob');     // "Hi Bob, I'm Ada"

Constructor parameter introspection (for DI):

function make(string $class): object {
    $rc = new ReflectionClass($class);
    $ctor = $rc->getConstructor();
    $args = [];
    foreach ($ctor->getParameters() as $param) {
        $type = $param->getType()->getName();
        $args[] = container_resolve($type);    // your DI logic
    }
    return $rc->newInstanceArgs($args);
}

This is roughly how Laravel and Symfony's containers wire dependencies — examine constructor types, look up implementations, instantiate with the right values.

ReflectionFunction for closures and global functions:

$rf = new ReflectionFunction(strlen(...));
echo $rf->getNumberOfParameters();    // 1

Performance: reflection is much slower than direct calls. Cache results when used in hot paths.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…