Skip to content

Instantly share code, notes, and snippets.

@linaori
Last active May 10, 2019 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save linaori/af50c1692e3d360d2e550b05e6121e58 to your computer and use it in GitHub Desktop.
Save linaori/af50c1692e3d360d2e550b05e6121e58 to your computer and use it in GitHub Desktop.

"inspect" keyword in PHP

The new inspect keyword is supposed to create bridge between generic type and variable inspection versus full-fledged reflection introspection. Hopefully this keyword can provide a replacement for a bunch of functions from https://www.php.net/manual/en/ref.var.php and https://www.php.net/manual/en/ref.classobj.php, while also making it fairly simple to get Reflection information of the variable.

I'm not sure at all if this is feasible or performance wise doable or even faster than the current implementations, it's merely an idea that popped up after a discussion on slack.

Examples for basic type usage

$foo = 1;
$inspected = inspect $foo;

$inspected->type;
// int

$inspected->class
// null

$inspected->export();
// 1

$inspected->dump();
// int(1)

$inspected->isInt();
// true

$inspected->isString();
// false

$foo = "foo";
$bar = &$foo;
(inspect $foo)->debugZvalDump();
// string(3) "foo" refcount(1)

With objects

$foo = new class {
    private string $prop;
    public function foo() {}
};
$inspected = inspect $foo;

// create or get a reflection instance of whatever is passed in
$ref = $inspect->reflection

$inspected->class
// class@anonymous\000php shell code0x7f6463e7e038

$inspected->instanceOf(stdClass::class)
// false

$inspected->hasParent()
// false

$inspected->parent->parent->parent->class
// null, but would go to the parent of the parent of the parent otherwise and echo the class

$inspected->hasProperty('prop');
// true

isset($inspected->properties['prop']);
// true

$inspected->properties['prop']->type
// string

// create or get a reflection instance of the property
$inspected->properties['prop']->reflection

$inspected->properties['prop']->dump();
// NULL

$inspected->hasMethod('foo')
// true

// create or get a reflection instance of the method
$inspected->methods['foo']->reflection

$callable = $inspected->methods['foo']->toCallable();
// same as
$callable = function (<get method signature for foo>) : <get return type of foo()> use ($foo) {
    return $foo->foo(...$args);
}
// as other languages would let you refer to the function reference `$foo->foo`

$inspected->methods['foo']->isCallable();
// true

Future possibilities

// annotations might receive a nice shortcut:
$foo = <FooAnnot('bar')> function () {};

(inspect $foo)->annotations[0]->dump();
// Annotation:FooAnnot() {
//   $value: string(3) "bar" 
// }


// annotations might receive a nice shortcut:
use Symfony\Component\Validator\Constraints as Assert;
class Foo
{
    <Assert\NotBlank()>
    private string $bar;
}

(inspect $foo)->properties['bar']->annotations;
// array(1) => [
//   Annotation:FooAnnot() {
//     $value: string(0) "" 
//   },
// ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment