7

I have a function that is being passed a Closure. I want to find out the name of the method that closure is derived from. When I call print_r, it outputs this:

Closure Object ( [static] => Array ( [listener] => Event_Subscriber_Calq@vendor_product_created [container] => Illuminate\Foundation\Application Object ... 

How do I acess that listener value? I tried ->static, ::$static, getStatic(), I can't think of any way to get the value.

Currently, my plan is to use output buffering to capture the output from a var_dump. I can't use print_r for this, because the closure contains a reference to and object that references itself, and print_r takes ages to handle the recursion. I also can't use var_export, because it does not include the value I want in the output. So, this is my solution:

ob_start(); var_dump($closure); $data = ob_get_clean(); $data = preg_replace('#^([^\n]*\n){4}#', '', $data); $data = preg_replace('#\n.*#', '', $data); $data = preg_replace('#.*string.[0-9]+. "(.*)".*#', '\1', $data); list($class, $method) = explode('@', $data); 

Which is horrible. Is there another way to do this? Maybe using reflection?

10
  • what is the origin of data? where'd you got this anyway? maybe your object has its getter method Commented May 6, 2015 at 11:44
  • It's actually coming from laravel, which does extend the core php closure class, but it does not add any new methods. Commented May 6, 2015 at 11:46
  • "...the name of the method that closure is derived from..." - you mean the name of the method that passed the Closure? Or the name of the method that executed/called the Closure? Commented May 6, 2015 at 11:49
  • Have you tried to convert this array from associative to numeric? php.net/manual/en/function.array-values.php Commented May 6, 2015 at 11:54
  • @Quasdunk a closure is normally a reference to an anonymous function, however it can also be a reference to a named function, which is what I believe I have here... although looking closer, I think it is more likely I am trying to retrieve data from the local scope of the closure... not sure that even makes sense. Well, whatever it is, I am trying to get the value of $obj->static->listener Commented May 6, 2015 at 11:55

2 Answers 2

8

I know this post is old, but in case someone is looking for info, you need to use ReflectionFunction:

$r = new ReflectionFunction($closure); var_dump($r, $r->getStaticVariables(), $r->getParameters()); 

Regards, Alex

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! This was exactly what I was looking for - I needed to get the class names of the listeners for a given event.
0

In a recent project, I decided on a declarative approach by using a wrapper class. The class allows setting a freeform string describing the callback's origin, and can be used as a direct replacement for the closure, as it implements the __invoke() method.

Example:

use ClosureTools; $closure = new NamedClosure( function() { // do something }, 'Descriptive text of the closure' ); // Call the closure $closure(); 

To access information on the closure:

if($closure instanceof NamedClosure) { $origin = $closure->getOrigin(); } 

Since the origin is a freeform string, it can be set to whatever is useful to identify the closure depending on the use case.

Here is the class skeleton:

<?php declare(strict_types=1); namespace ClosureTools; use Closure; class NamedClosure { /** * @var Closure */ private $closure; /** * @var string */ private $origin; /** * @param Closure $closure * @param string $origin */ public function __construct(Closure $closure, string $origin) { $this->closure = $closure; $this->origin = $origin; } /** * @return string */ public function getOrigin() : string { return $this->origin; } public function __invoke() { return call_user_func($this->closure, func_get_args()); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.