Zaczynam nową wtyczkę w stylu OOP
Co oznacza dla Ciebie „styl OOP”? Zawijasz wszystkie funkcje w instrukcję klasy? Więc robisz to źle. Tęsknisz za klasą jako przestrzenią nazw.
i właśnie dowiedziałem się, że moja główna klasa jest często zaszczepiona
Co?
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(); } );
Wypróbuj i policz liczbę utworzonych plików. Jeśli spróbuję, dla każdego żądania strony zostanie utworzony jeden plik. Oznacza to tylko jedno wystąpienie klasy Foo dla każdego żądania strony.
Spróbujmy wezwania do działania
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(); } );
Jeśli zajrzę do mojego katalogu treści wp, znalazłem dwa pliki. Już nie. Jeden plik jest tworzony podczas tworzenia instancji klasy. Jeden jest tworzony po zakończeniu akcji.
OK, zróbmy kilka głupich rzeczy z naszą instancją. Usuń add_action( 'plugins_loaded', .. )
i dodaj ten kod zamiast:
function bar( $foo ) {
$baz = $foo;
return $baz;
}
$f = new Foo();
$GLOBALS['foo'] = $f;
$f2 = $f;
$f3 = &$f;
$f4 = bar( $f2 );
$f5 = bar( $f3 );
Ile oczekujesz plików? Oczekuję dwóch. Jeden od konstruktora, drugi od metody.
Nowa instancja jest tworzona tylko wtedy, gdy new
używany jest operator.
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 );
Teraz liczę cztery pliki. Dwa z konstruktora i dwa z metody. Wynika to z faktu, że WordPress najpierw dołącza wtyczkę, a następnie wykonuje hak akcji plugins_loaded
.
Najlepszą praktyką jest używanie haka akcji plugins_loaded
zamiast tworzenia instancji z funkcji, ponieważ jeśli plik wtyczki jest zawarty w dowolnym miejscu (np. W innym pliku wtyczki), nowe wystąpienie klasy jest tworzone za każdym razem, gdy plik jest dołączany. Hak akcji plugins_loaded
jest wykonywany tylko raz dla każdego żądania strony.