Title: Using PHP closures in class-based plugin
Last modified: August 22, 2016

---

# Using PHP closures in class-based plugin

 *  Resolved [DanielAGW](https://wordpress.org/support/users/danielagw/)
 * (@danielagw)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/using-php-closures-in-class-based-plugin/)
 * Hello,
    I was recently updating my plugin when I realized that I don’t know how
   to use PHP closures properly within filters/hooks in a class-based plugin.
 * Basically this is what I wanted to do:
 *     ```
       add_action('admin_bar_menu', function(){
       	add_filter('get_avatar', 'some_function');
       }, 0);
       ```
   
 * So we have two typical WP hooks, one inside another – we’re using anonymous function
   with `admin_bar_menu` action and we’re filtering `get_avatar` with the output
   of function named `some_function`.
 * That’s easy and it would have worked… if only my plugin wasn’t an object. And
   because I realised I don’t know how to use anonymous functions with WP hooks 
   in class-based plugins, I ended up doing this:
 *     ```
       class Some_plugin {
   
       	public function __construct(){
       		add_action('admin_bar_menu', array($this, 'some_unnecessary_function'), 0);
       	}
   
       	public function some_unnecessary_function(){
       		add_filter('get_avatar', array($this, 'some_function'), 10);
       	}
   
       	public function some_function(){
       		//do something
       	}
   
       }
   
       $some_plugin = new Some_plugin();
       ```
   
 * This solution works, of course, but I am not very happy with the way it is written.
   Declaring another method just to make it work, instead of using perfectly-suited
   closures which were born to serve exactly this purpose, made me look for the 
   solution, but I just couldn’t find anything. I know how to use closures with 
   WP hooks, I know how to write object-oriented plugins, but I don’t know how to
   use closures with WP hooks in an object-oriented plugin. Any ideas?
 * Thank you for your time.
 * Cheers,
    Daniel

Viewing 9 replies - 1 through 9 (of 9 total)

 *  [Anastis Sourgoutsidis](https://wordpress.org/support/users/anastis/)
 * (@anastis)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/using-php-closures-in-class-based-plugin/#post-5881249)
 * Have you tried this (inside the class)?
 *     ```
       add_action('admin_bar_menu', function(){
       	add_filter('get_avatar', array($this, 'some_function'));
       }, 0);
       ```
   
 * Or this outside the class:
 *     ```
       add_action('admin_bar_menu', function(){
       	add_filter('get_avatar', 'Some_plugin::some_function');
       }, 0);
       ```
   
 *  [Rafał Gicgier](https://wordpress.org/support/users/gicolek/)
 * (@gicolek)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/using-php-closures-in-class-based-plugin/#post-5881259)
 * I’m not a fan of using closures with WP hooks, because they can’t be unhooked
   then. This limits the ability of anyone else using your code and trying to modify
   its behavior.
 * Nonetheless the closure shouldn’t be a problem. Have you tested the hook using
   __CLASS__ instead of $this in the inner function call? If you hook something 
   and then use the hook again it will not be seen as a part of the object of the
   class created.
 * For instance:
 *     ```
       add_action( 'admin_bar_menu' , function(){
       	add_filter( 'get_avatar', array( __CLASS__, 'some_function' ) );
       }, 0 );'
       ```
   
 * If this won’t work make the function static and use the class name instead of
   the class.
 * The problem is connected with the fact that the inner function is called from
   within the place where first action is called (which means outside of the class),
   so there’s no object to apply the call to.
 *  Thread Starter [DanielAGW](https://wordpress.org/support/users/danielagw/)
 * (@danielagw)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/using-php-closures-in-class-based-plugin/#post-5881280)
 * **[@anastis](https://wordpress.org/support/users/anastis/) Sourgoutsidis:** Thanks,
   but it’s the first thing I tried. Arguments are not passed to `some_function`
   when using the first method.
 * **[@gicolek](https://wordpress.org/support/users/gicolek/):** `__CLASS__` gives
   the same result as `$this` – arguments are not passed to the function (missing
   arguments warning). I kind of understand why it happens – when I apply action/
   filter to `array($this, 'foo')`, the hook will execute `foo()` from within the
   class. When I use closure instead, there is no way to execute instructions (entered
   in a form of anomyous function) within my class. This construction would make
   sense in this case:
 *     ```
       array($this, function(){
       	add_filter('get_avatar', array($this, 'some_function'));
       })
       ```
   
 * So that closure would be part of the array along with `$this`, just like we do
   it when we use an array with `$this` and a method name. Only in this case, instead
   of function name, a full function in a form of closure would be used.
 *  [Rafał Gicgier](https://wordpress.org/support/users/gicolek/)
 * (@gicolek)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/using-php-closures-in-class-based-plugin/#post-5881284)
 * Yes Daniel, that’s exactly what I had written. Actually I shouldn’t have proposed
   the __CLASS__ as per your description, as it contradicts to what I wrote later
   on 🙂 The problem is the scope here. It’s not only caused by the closure, it’s
   caused by the fact that filters / actions are run outside the class; to be precise
   in the place where corresponding apply_filters, do_action calls have been specified.
 * You can also declare your function static and reference it directly via
 * `array( CLASS_NAME, method_name);`
 * Does the method described above by you work at all?
 *  Thread Starter [DanielAGW](https://wordpress.org/support/users/danielagw/)
 * (@danielagw)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/using-php-closures-in-class-based-plugin/#post-5881285)
 * > it’s caused by the fact that filters / actions are run outside the class; to
   > be precise in the place where corresponding apply_filters, do_action calls 
   > have been specified.
 * But it does work perfectly when I use normal function call instead of closure.
   I apply action callback to `function_x()` which applies filter callback to `function_y()`
   and it works. It only doesn’t work when I don’t use callback to `function_x()`
   and apply filter callback to `function_y()` in action callback with a closure.
   That’s what I have written in the first post:
 *     ```
       class Some_plugin {
   
       	public function __construct(){
       		add_action('admin_bar_menu', array($this, 'some_unnecessary_function'), 0);
       	}
   
       	public function some_unnecessary_function(){
       		add_filter('get_avatar', array($this, 'some_function'), 10);
       	}
   
       	public function some_function(){
       		//do something
       	}
   
       }
   
       $some_plugin = new Some_plugin();
       ```
   
 * `some_unnecessary_function()` represents aforementioned `function_x()`, and `
   some_function()` is `function_y()`. This solution works perfectly. The problem
   is that I don’t want to define `some_unnecessary_function()` just for the sake
   of defining it so I can callback to it later on. I want to use closure in `__construct()`
   in `add_action()`. And I can’t do that, because I can’t create array with `$this`
   and anonymous function, just like I can create array with `$this` and a function
   name.
 * So the scope is not a direct problem here. The problem is that I cannot correctly
   specify the scope when using closures to WP hooks. I can do it easily when I 
   use callback to another method, but I cannot do it when I use closure.
 * > Does the method described above by you work at all?
 * Not at all, it was more of a pseudo-code. Just how I would imagine it working.
   Just like we use `array($this, 'function_name')`, it would make sense to use `
   array($this, function(){})` to represent the same thing, only without the need
   to define `function_name()` just for the sake of defining it to callback to it
   later.
 * **EDIT:**
    Okay, after finishing this post I realised that you were right all
   along and it makes sense. And it IS all about the scope and closures are not 
   to blame here, it’s all because of the place where this closure is located. It’s
   still very, very blurry to me, though. I’ve used to think of closures as a String,
   for example, whereas the function definition and its content as a variable with
   this String (or any other data type) assigned to it. So we can do this: `some_random_function('
   text');` But we can also do this:
 *     ```
       $some_string = 'text';
       some_random_function($some_string);
       ```
   
 * Technically, it does not matter which option we choose, the effect will be the
   same (except for minor performance difference). This is how I used to think about
   using WP hooks with function names or with closures – we can define the function
   and callback to it in the hook, or we can callback directly to a closure, which
   would result in the same thing, just without having the function defined separately.
   But I begin to understand that this is not the same, right? So when we use hook,
   like: `add_action('some_hook', array($this, 'foo')`, we are actually passing 
   the object we want to use the method with (hence `$this` – cause we want to use
   it with current object) and running its `foo()` method? But I still can’t get
   my head around why it is not possible with closures! If anonymous function was
   used instead of ‘foo’, we should also be able to pass current object and use 
   anonymous function within the scope of this object. I don’t get it 🙁
 * Sorry for such a long post, the more I think about it the less I know…
 *  [Rafał Gicgier](https://wordpress.org/support/users/gicolek/)
 * (@gicolek)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/using-php-closures-in-class-based-plugin/#post-5881287)
 * Hey Daniel,
 * > So when we use hook, like: add_action(‘some_hook’, array($this, ‘foo’), we 
   > are actually passing the object we want to use the method with (hence $this–
   > cause we want to use it with current object) and running its foo() method?
 * That’s correct!
 * > But I still can’t get my head around why it is not possible with closures!
 * Educating myself a bit: perhaps using the [alternate](http://php.net/manual/en/functions.anonymous.php#example-186)
   syntax for closures would help again?
 * Anyway the best way to identify the issue is to actually look at the source of
   the apply_filters, do_action, add_filter and add_action methods. Dwelling in 
   there you’ll see that do_action is a tricky wrapper to apply_filters, and apply_filters
   is using call_user_func_array twice – this is why our hooked function is the 
   executed.
 * _However this function is executed from the place where one of the hooks has 
   been defined. Which means from OUTSIDE of the class. So we actually need to make
   the function public and then it will be called automatically via PHP. _
 * The above is bull*hit actually 😛 I was wrong all the way. I’m correct up to 
   a point. I think that you can’t use the object from the closure call, because
   the object will not be a part of the corresponding scope in that case.
 * And the reason for that is that the following code…
 *     ```
       	`add_action( 'init', function() {
       			add_filter('the_content', function(){
       				return 'aabbbb';
       			}, 9999);
       		}, 99999 );`
       ```
   
 * … works from within the constructor of a class properly. I have just tested it.
   I think that the problem with your code lies in lack of priority of the hook.
   Have you tried altering its pririty like I did?
 * By the way look [on a comment about closures with filters](https://github.com/WordPress/WordPress/blob/master/wp-includes/plugin.php#L878).
 *  Thread Starter [DanielAGW](https://wordpress.org/support/users/danielagw/)
 * (@danielagw)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/using-php-closures-in-class-based-plugin/#post-5881305)
 * Thank you so much **gicolek** for your help. I just realized that… everything
   works just fine. The missing arguments warning I was getting was present only
   when I didn’t include `$accepted_args` in the hook. So the first solution proposed
   by **Anastis Sourgoutsidis** caused missing arguments error in my function. At
   first I have written it the same way he did and that’s why I couldn’t get it 
   right. But doing it this way:
 *     ```
       add_action('admin_bar_menu', function(){
       	add_filter('get_avatar', array($this, 'some_function'), 10, 5);
       }, 0);
       ```
   
 *  works just as it should. I thought that the warning is caused by not passing
   arguments to my method because of scope, so I tried looking for solution to run
   closure in correct scope. And it turned that the scope is okay, it’s just the
   arguments weren’t passed because I haven’t specified them…
 * > I think that you can’t use the object from the closure call, because the object
   > will not be a part of the corresponding scope in that case.
 * Well, actually we can do it. PHP has no problem with that and the reason why 
   I had problems was only because I wasn’t clever enough to think that “missing
   arguments” warning may actually mean… well, missing arguments in function. Not
   a problem with closure, scope or anything else. Just missing arguments because
   I haven’t specified `$accepted_args` in the hook.
 * So sorry for misguiding you, I wish I examined it more thoroughly beforehand.
   Good thing is that I learned much more about closures, WP and PHP in general,
   so thank you for your time and willingness to help.
 * After reading a lot about closures I realized that they are very weird. Not as
   weird as they are in JS, but in JS at least they make much more sense, because
   the language is much more event-driven. Closures in PHP seem very unnatural to
   me.
 * **EDIT:**
    I think this will only work with PHP 5.4+. See Changelog of anonymous
   functions – [http://php.net/manual/en/functions.anonymous.php](http://php.net/manual/en/functions.anonymous.php)
   I wonder why `$this` couldn’t be used in anonymous functions before PHP 5.4? 
   Anonymous functions are great for callbacks, and today, when 90% of programming
   is OOP, we want to use this object also in anonymous functions… Well, fortunately
   it works in 5.4+.
 *  Thread Starter [DanielAGW](https://wordpress.org/support/users/danielagw/)
 * (@danielagw)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/using-php-closures-in-class-based-plugin/#post-5881306)
 * I just checked it on my local environment (with PHP 5.3) and that’s correct, 
   it doesn’t work. So the problem wasn’t only with callback arguments, it was `
   $this` in closure as well. I did first tests on local environment with PHP 5.3
   and it didn’t work, even though I was doing everything right. It didn’t work 
   because I was using `$this` in closure which gave me `call_user_func_array() 
   expects parameter 1 to be a valid callback, first array member is not a valid
   class name or object` warning, which I didn’t quite understand. Then I switched
   to my remote environment to do further tests (with PHP 5.4), but in this case
   I forgot to specify the arguments param in the hook and it didn’t work because
   of my function construction (function was executed properly). So there were actually
   two problems happening due to different reasons.
 * I’m glad to have this finally sorted out. Great learning experience, thanks **
   gicolek** and **Anastis Sourgoutsidis**.
 *  [Rafał Gicgier](https://wordpress.org/support/users/gicolek/)
 * (@gicolek)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/using-php-closures-in-class-based-plugin/#post-5881308)
 * Hey Daniel,
 * It was a learning experience for me either. I’ve mixed both closures and objects
   in my mind somehow giving my answers 😉
 * Good luck with your code!
 * And please bear in mind inability to unhook stuff with closures.

Viewing 9 replies - 1 through 9 (of 9 total)

The topic ‘Using PHP closures in class-based plugin’ is closed to new replies.

 * In: [Hacks](https://wordpress.org/support/forum/plugins-and-hacks/hacks/)
 * 9 replies
 * 3 participants
 * Last reply from: [Rafał Gicgier](https://wordpress.org/support/users/gicolek/)
 * Last activity: [11 years, 2 months ago](https://wordpress.org/support/topic/using-php-closures-in-class-based-plugin/#post-5881308)
 * Status: resolved

## Topics

### Topics with no replies

### Non-support topics

### Resolved topics

### Unresolved topics

### All topics
