1

Most of the wordpress plugins I found is functions based, for example, the offical akismet plugin

function akismet_init() {
    global $wpcom_api_key, $akismet_api_host, $akismet_api_port;


    // ...
}
add_action('init', 'akismet_init');

There are a few issues with this approach:

  • you cannot share state between function, so you must use global variables
  • hard to do unit test, i.e. no way to mock

My initial attempt is to wrap into an Object, e.g. in the akismet.php

class Akismet {

    protected static $akismet_api_host;
    protected static $akismet_api_port;

    public function __construct()
    {
        add_action('init', array($this, 'init'));
    }

    public function init()
    {
       // Do my init here
    }
}

$GLOBALS['Akismet'] = new Akismet();

However, there is still some issues with this approach

  • I need to put most of my methods as public to be callable (which is bad)
  • You cannot pass variable into callback without using anonymous callback (and if you use anonymous callback, you cannot remove them by using remove_action/remove_filter)

e.g.

public function __construct()
{
    $foo = 'bar';
    add_action('init', function() use ($foo) {
      echo $foo; // You can pass variable by using callback but you cannot this action later!
    });
}

So, how to have the flexibility to pass variable into any Wordpress' action/filter and while maintain the flexibility to cancel them later?

1

One way could be to use classes and objects. It's more efficient considering reusability, collective work and more. I don't think it's bad to use global variables if you know what you're doing.

So I would recommand you to use OOP (object oriented programming) especially with inheritance and polymorphism.

  • Actually I 've done this but encountered another issue with variable passing. I've updated my question to show more code from my existing works, thanks. – Yoga Jul 23 '14 at 4:24
1

So, how to have the flexibility to pass variable into any Wordpress' action/filter and while maintain the flexibility to cancel them later?

You could assign the function to one of the class's properties:

public function __construct()
{
    $foo = 'bar';

    $this->init_func = function() use ( $foo ) {
        echo $foo;
    };

    add_action( 'init', $this->init_func );
}

Then later you can do this:

remove_action( 'init', $this->init_func );

But please don't do that.

I think it would make testing a nightmare. Also, you are in a class, where you can assign the value you want to use in the function to a property:

public function __construct()
{
    $this->foo = 'bar';

    add_action( 'init', array( $this, 'init' ) );
}

public function init()
{
    echo $this->foo;
}

That's kind of what classes are for. :-)


You seem to have a fear of having public class methods. Why? You want WordPress to be able to invoke your class' code, so it has to have some public API which will allow that. PHP classes provide public methods, so you might as well use them, rather than trying to reinvent the wheel. :-)

  • You code solved the variable passing issue, but remove_action cannot remove a callback, it only accept string, so this issue is still blocking for me still using function based approach: codex.wordpress.org/Function_Reference/remove_action – Yoga Jul 23 '14 at 14:04
  • @Yoga It does work; you can test it for yourself. I've updated that page to say that it is a callable not strictly a string. – J.D. Jul 23 '14 at 19:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.