Je commence un nouveau plugin avec le style OOP
Que signifie pour vous le «style OOP»? Envelopper toutes vos fonctions avec une instruction de classe? Ensuite, vous le faites mal. Vous utilisez mal la classe comme espace de noms.
et je viens de découvrir que ma classe principale est instanciée beaucoup
Hein?
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(); } );
Essayez-le et comptez le nombre de fichiers créés. Si je l'essaye, il y a un fichier créé pour chaque demande de page. Cela signifie, une seule instance de la classe Foo pour chaque demande de page.
Essayons un appel à l'action
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(); } );
Si je regarde dans mon répertoire wp-content, j'ai trouvé deux fichiers. Pas plus. Un fichier est créé lors de la création de l'instance de classe. Et un est créé lorsque l'appel à l'action est terminé.
OK, faisons des choses stupides avec notre instance. Supprimez le add_action( 'plugins_loaded', .. )
et ajoutez ce code à la place:
function bar( $foo ) {
$baz = $foo;
return $baz;
}
$f = new Foo();
$GLOBALS['foo'] = $f;
$f2 = $f;
$f3 = &$f;
$f4 = bar( $f2 );
$f5 = bar( $f3 );
Combien de fichiers attendez-vous? J'en attends deux. Un du constructeur, un de la méthode.
Une nouvelle instance n'est créée que lorsque l' new
opérateur est utilisé.
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 );
Maintenant, je compte quatre fichiers. Deux du constructeur et deux de la méthode. En effet, WordPress inclut d'abord le plugin, puis effectue le crochet d'action plugins_loaded
.
La meilleure pratique consiste à utiliser le hook d'action plugins_loaded
au lieu de créer une instance à partir d'une fonction car, si le fichier du plugin est inclus n'importe où (par exemple dans un autre fichier de votre plugin), une nouvelle instance de la classe est créée chaque fois que le fichier est inclus. Le hook d'action plugins_loaded
n'est effectué qu'une seule fois pour chaque demande de page.