Setiap kali plugin membuat new MyClass();
, itu harus menetapkannya ke variabel bernama unik. Dengan begitu, instance kelas dapat diakses.
Jadi jika dia melakukannya $myclass = new MyClass();
, maka Anda bisa melakukan ini:
global $myclass;
remove_action( 'wp_footer', array( $myclass, 'my_action' ) );
Ini berfungsi karena plugin termasuk dalam namespace global, jadi deklarasi variabel implisit di bagian utama plugin adalah variabel global.
Jika plugin tidak menyimpan pengenal kelas baru di suatu tempat , maka secara teknis, itu bug. Salah satu prinsip umum Pemrograman Berorientasi Objek adalah bahwa objek yang tidak dirujuk oleh beberapa variabel di suatu tempat dapat dibersihkan atau dihilangkan.
Sekarang, PHP khususnya tidak melakukan ini seperti Java, karena PHP adalah implementasi OOP setengah-arsed. Variabel instance hanya string dengan nama objek unik di dalamnya, semacam itu. Mereka hanya bekerja karena cara interaksi nama fungsi variabel bekerja dengan ->
operator. Jadi melakukan sesuatu new class()
memang dapat bekerja dengan sempurna, hanya dengan bodoh. :)
Jadi, intinya, jangan pernah lakukan new class();
. Lakukan $var = new class();
dan buat agar $ var dapat diakses dengan cara tertentu untuk bit lain untuk merujuknya.
Edit: bertahun-tahun kemudian
Satu hal yang saya lihat banyak plugin lakukan adalah menggunakan sesuatu yang mirip dengan pola "Singleton". Mereka membuat metode getInstance () untuk mendapatkan instance tunggal dari kelas. Ini mungkin solusi terbaik yang pernah saya lihat. Plugin contoh:
class ExamplePlugin
{
protected static $instance = NULL;
public static function getInstance() {
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
}
Pertama kali getInstance () dipanggil, instantiate kelas dan menyimpan pointer-nya. Anda dapat menggunakannya untuk mengaitkan tindakan.
Satu masalah dengan ini adalah Anda tidak bisa menggunakan getInstance () di dalam konstruktor jika Anda menggunakan hal seperti itu. Ini karena baru memanggil konstruktor sebelum menetapkan $ instance, jadi memanggil getInstance () dari konstruktor mengarah ke loop tak terbatas dan merusak segalanya.
Salah satu solusinya adalah tidak menggunakan konstruktor (atau, setidaknya, tidak menggunakan getInstance () di dalamnya), tetapi untuk secara eksplisit memiliki fungsi "init" di kelas untuk mengatur tindakan Anda dan semacamnya. Seperti ini:
public static function init() {
add_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
}
Dengan sesuatu seperti ini, di akhir file, setelah kelas telah ditentukan dan semacamnya, instantiating plugin menjadi sesederhana ini:
ExamplePlugin::init();
Init mulai menambahkan tindakan Anda, dan dengan melakukan hal itu memanggil getInstance (), yang membuat instance kelas dan memastikan hanya satu saja yang ada. Jika Anda tidak memiliki fungsi init, Anda akan melakukan ini untuk membuat instance kelas pada awalnya sebagai gantinya:
ExamplePlugin::getInstance();
Untuk menjawab pertanyaan awal, menghapus kait tindakan dari luar (alias, di plugin lain) kemudian dapat dilakukan seperti:
remove_action( 'wp_footer', array( ExamplePlugin::getInstance(), 'my_action' ) );
Masukkan itu ke dalam sesuatu yang dikaitkan dengan plugins_loaded
kait tindakan dan itu akan membatalkan tindakan yang dikaitkan oleh plugin asli.