Is There a Plugin Life Cycle Documentation?

I’m starting a new plugin with OOP style

What does ‘OOP style’ means for you? Wrapping all your functions with a class statement? Then you doing it wrong. You missuse the class as namespace.

and I just found out that my main class is being instanciated a lot

Huh?

class Foo
{
  public function __construct() {
    // assuming your wp-content dir is writeable
    $filename = sprintf( WP_CONTENT_DIR . '/dummyfile-%d.txt', time() );
    $handle = fopen( $filename, 'w' );
    if ( $handle ) {
      fputs( $handle, '-' );
      fclose( $handle );
    }
  }
}

add_action( 'plugins_loaded', function() { new Foo(); } );

Try it and count the number of files created. If i try it out, there is one file created for each page request. This means, only one instance of the Foo class for each page request.

Let’s try a action call

class Foo
{
    public function __construct() {

        $this->write_file( 'in_constructor' );
        add_action( 'init', array( $this, 'action_test' ), 10, 0 );

    }

    public function action_test() {

        $this->write_file( 'in_method_with_action_call' );

    }

    public function write_file( $filename ) {

      // assuming your wp-content dir is writeable
      $counter = 1;
      $fname = sprintf( WP_CONTENT_DIR . '/%s-%d.txt', $filename, $counter );

      if ( file_exists( $fname ) ) {
        preg_match( '/(\d)\.txt/is', $fname, $match );
          if ( isset( $match[1] ) ) {
              $counter = (int) $match[1] + 1;
              $fname = sprintf( WP_CONTENT_DIR . '/%s-%d.txt', $filename, $counter );
          }
      }

      $handle = fopen( $fname, 'a+' );
      if ( $handle ) {
          fputs( $handle, '-' );
          fclose( $handle );
      } else {
          throw new Exception( "Cannot open file {$fname} for writing" );
      }

    }
}

add_action( 'plugins_loaded', function() { new Foo(); } );

If I look in my wp-content dir, I found two files. No more. One file is created when the class instance is created. And one is created when the action call is done.

OK, let’s do some stupid things with our instance. Remove the add_action( 'plugins_loaded', .. ) and add this code instead:

function bar( $foo ) {

    $baz = $foo;
    return $baz;
}

$f = new Foo();
$GLOBALS['foo'] = $f;

$f2 = $f;
$f3 = &$f;

$f4 = bar( $f2 );
$f5 = bar( $f3 );

How many files do you expect? I expect two. One from the constructor, one from the method.

A new instance is created only when the new operator is used.

add_action( 'plugins_loaded', 'new_foo', 10, 0 );

function new_foo() {
    // first instance
    new Foo();
}

function bar( $foo ) {
    $baz = $foo;
    return $baz;
}

// second instance here!!
$f = new Foo();
$GLOBALS['foo'] = $f;

$f2 = $f;
$f3 = &$f;

$f4 = bar( $f2 );
$f5 = bar( $f3 );

Now I count four files. Two from the constructor and two from the method. This is because WordPress first include the plugin and then do the action hook plugins_loaded.

Best practice is to use the action hook plugins_loaded instead of creating an instance out of a function because, if the plugin file is included anywhere (e.g. in another file of your plugin), a new instance of the class is created everytime the file is included. The action hook plugins_loaded is done only once for every page request.

Leave a Comment