Estoy comenzando un nuevo complemento con estilo OOP
¿Qué significa 'estilo OOP' para ti? ¿Envolviendo todas sus funciones con una declaración de clase? Entonces lo estás haciendo mal. Usas mal la clase como espacio de nombres.
y acabo de descubrir que mi clase principal está siendo instanciada mucho
¿Eh?
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(); } );
Pruébelo y cuente la cantidad de archivos creados. Si lo pruebo, hay un archivo creado para cada solicitud de página. Esto significa que solo una instancia de la clase Foo para cada solicitud de página.
Probemos una llamada a la acción
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 busco en mi directorio wp-content, encontré dos archivos. No más. Se crea un archivo cuando se crea la instancia de clase. Y se crea uno cuando finaliza la llamada a la acción.
Bien, hagamos algunas estupideces con nuestra instancia. Elimine add_action( 'plugins_loaded', .. )
y agregue este código en su lugar:
function bar( $foo ) {
$baz = $foo;
return $baz;
}
$f = new Foo();
$GLOBALS['foo'] = $f;
$f2 = $f;
$f3 = &$f;
$f4 = bar( $f2 );
$f5 = bar( $f3 );
¿Cuántos archivos esperas? Espero dos. Uno del constructor, uno del método.
Se crea una nueva instancia solo cuando new
se utiliza el operador.
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 );
Ahora cuento cuatro archivos. Dos del constructor y dos del método. Esto se debe a que WordPress primero incluye el complemento y luego realiza el gancho de acción plugins_loaded
.
La mejor práctica es usar el gancho de acción en plugins_loaded
lugar de crear una instancia a partir de una función porque, si el archivo de complemento se incluye en algún lugar (por ejemplo, en otro archivo de su complemento), se crea una nueva instancia de la clase cada vez que se incluye el archivo. El enlace de acción plugins_loaded
se realiza solo una vez por cada solicitud de página.