Estoy comenzando un nuevo complemento con estilo OOP
¿Qué significa 'estilo OOP' para ti? ¿Envolviendo todas tus funciones con una declaración de clase? Entonces lo haces mal. Mal uso de 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 de 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 miro en mi directorio wp-content, encontré dos archivos. No más. Se crea un archivo cuando se crea la instancia de clase. Y uno se crea cuando se realiza la llamada de 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 se usa el operador new
.
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 plugins_loaded
en lugar de crear una instancia a partir de una función porque, si el archivo de complemento se incluye en cualquier lugar (por ejemplo, en otro archivo de su complemento), se crea una nueva instancia de la clase Cada vez que el archivo está incluido. El gancho de acción plugins_loaded
se realiza solo una vez por cada solicitud de página.