DEV Community

Cover image for How to use the PHP Reflection API for Inspecting Closure Contents [2/4]
Nick Ciolpan for Graffino

Posted on

How to use the PHP Reflection API for Inspecting Closure Contents [2/4]

The Reflection API in PHP is a set of classes that allow you to introspect your code. It provides the ability to retrieve detailed information about classes, methods, properties, and functions at runtime, such as their names, parameters, and modifiers (like public, private, protected), among other things. It's commonly used for advanced tasks like building development tools, debuggers, or components for a dependency injection container.

Closures (or anonymous functions) in PHP are considered "black boxes" because they encapsulate their behavior and environment when defined. This means that their internal variables and code can't be directly accessed or inspected from the outside like regular variables - you can only interact with them through their inputs and outputs. When you try to dump a closure with var_dump(), print_r(), or Laravel's dd(), you don't see the actual PHP code inside the closure. This is why you need tools like the Reflection API to inspect their contents.

$getClosureContents = function(\Closure $closure)
{
    $reflection = new ReflectionFunction($closure);
    $closureCode = file($reflection->getFileName());

    $startLine = $reflection->getStartLine();
    $endLine = $reflection->getEndLine();

    $contents = array_slice($closureCode, $startLine - 1, $endLine - $startLine + 1);

    return implode('', $contents);
}
Enter fullscreen mode Exit fullscreen mode

What we're doing here is pretty simple: We find the exact PHP file that has the closure, read the content of this file, get all the lines from the start to the end, and put the function back together as a multiline string. But this process would not be possible without the useful features of PHP's Reflection.

$closureContents = array_map($getClosureContents, $gates);
Enter fullscreen mode Exit fullscreen mode

Will put out:

[
     "viewHorizon" => """
               Gate::define('viewHorizon', function ($user) {\n
                   return in_array($user->email, [\n
                       //\n
                   ]);\n
               });\n
       """,
     "viewTelescope" => """
               Gate::define('viewTelescope', function ($user) {\n
                   return in_array($user->email, [\n
                       //\n
                   ]);\n
               });\n
       """,
   ]
Enter fullscreen mode Exit fullscreen mode

Now we are able to: Create a Laravel Command to Display All Authorization Gates Similar to route:list

Top comments (0)