Contoh hipotetis tetapi penerapan dunia nyata (untuk seseorang yang belajar, seperti saya).
Diberikan kode ini:
<?php
function send_money_to_grandma() {
internetofThings("send grandma","$1");
}
add_action('init','send_money_to_grandma');
add_action('init','send_money_to_grandma');
ok, sekarang saya membuka situs WP saya dan masuk. Saya melintasi beberapa halaman di Admin. Aksi 'init' menyala total 100 kali sebelum baterai laptop saya mati.
Pertanyaan pertama: Berapa banyak uang yang kami kirim ke nenek? Apakah $ 1, $ 2, $ 100 atau $ 200 (atau yang lainnya?)
Jika Anda juga bisa menjelaskan jawaban Anda, itu akan luar biasa.
Pertanyaan kedua: Jika kita ingin memastikan bahwa kita hanya mengirim nenek $ 1, apa cara terbaik untuk melakukannya? Variabel global (semaphore) yang disetel 'benar' saat pertama kali kami mengirim $ 1? Atau adakah tes lain untuk melihat apakah suatu tindakan sudah terjadi dan mencegahnya menembak berulang kali?
Pertanyaan ketiga: Apakah ini sesuatu yang dikhawatirkan pengembang plugin? Saya menyadari bahwa contoh saya konyol tetapi saya memikirkan masalah kinerja dan efek samping lain yang tidak terduga (misalnya jika fungsi memperbarui / memasukkan ke basis data).
Jawaban:
Berikut adalah beberapa pemikiran acak tentang ini:
Pertanyaan 1
Untuk 100 halaman memuat, kami mengiriminya 100 x $ 1 = $ 100.
Di sini yang kita maksud sebenarnya adalah
100 x do_action( 'init' )
panggilan.Tidak masalah bahwa kami menambahkannya dua kali dengan:
karena callback dan prioritas (default 10) identik .
Kita dapat memeriksa bagaimana
add_action
ini hanyalah pembungkus untukadd_filter
yang membangun$wp_filter
array global :Namun, jika kami mengubah prioritas:
maka kami akan mengirimnya 2 x $ 1 per halaman memuat atau $ 200 untuk 100 halaman memuat.
Sama jika panggilan baliknya berbeda:
Pertanyaan # 2
Jika kami hanya ingin mengirimnya sekali per pemuatan halaman , maka ini harus dilakukan:
karena
init
kailnya hanya sekali ditembakkan. Kami mungkin memiliki kait lain yang menyala berkali-kali per pemuatan halaman.Mari kita panggil:
tetapi apa yang terjadi jika
someaction
kebakaran 10 kali per memuat halaman?Kita dapat menyesuaikan
send_money_to_grandma()
fungsi denganatau gunakan variabel statis sebagai penghitung:
Jika kami hanya ingin menjalankannya sekali saja!, Maka kami mungkin mendaftarkan opsi di
wp_options
tabel melalui API Opsi :Jika kami ingin mengirim uang kepadanya sekali setiap hari, maka kami dapat menggunakan API Sementara
atau bahkan menggunakan wp-cron.
Perhatikan bahwa Anda mungkin memiliki panggilan ajax. demikian juga.
Ada beberapa cara untuk memeriksanya, misalnya dengan
DOING_AJAX
Mungkin juga ada pengalihan, yang dapat mengganggu aliran.
Maka kita mungkin ingin membatasi untuk backend saja,
is_admin()
atau tidak:! is_admin()
.Pertanyaan # 3
ya ini penting.
Jika kita ingin membuat nenek kita sangat bahagia, kita akan melakukannya:
tapi ini akan sangat buruk untuk kinerja ... dan dompet kami ;-)
sumber
Ini lebih merupakan komentar untuk jawaban Birgire yang sangat bagus daripada jawaban yang lengkap, tetapi harus menulis kode, komentar tidak cocok.
Dari jawaban itu mungkin tampak bahwa satu-satunya alasan mengapa tindakan ditambahkan sekali dalam kode sampel OP, bahkan jika
add_action()
dipanggil dua kali, adalah kenyataan bahwa prioritas yang sama digunakan. Itu tidak benar.Dalam kode
add_filter
bagian penting adalah_wp_filter_build_unique_id()
panggilan fungsi, yang menciptakan id unik per panggilan balik .Jika Anda menggunakan variabel sederhana, seperti string yang menyimpan nama fungsi, misalnya
"send_money_to_grandma"
, maka id akan sama dengan string itu sendiri, jadi jika prioritasnya sama, menjadi id juga sama, panggilan balik ditambahkan satu kali.Namun, hal-hal tidak selalu sederhana seperti itu. Callback bisa berupa apa saja yang ada
callable
di PHP:Dua yang pertama diwakili, masing-masing, dengan string dan array 2 string (
'send_money_to_grandma'
danarray('MoneySender', 'send_to_grandma')
) sehingga id selalu sama, dan Anda dapat yakin bahwa callback ditambahkan satu kali jika prioritasnya sama.Dalam semua 3 kasus lainnya, id bergantung pada instance objek (fungsi anonim adalah objek dalam PHP) sehingga callback ditambahkan hanya sekali jika objek adalah instance yang sama , dan penting untuk mencatat instance yang sama dan kelas yang sama Ada dua hal yang berbeda.
Ambil contoh ini:
Berapa banyak dolar yang kami kirim per pemuatan halaman?
Jawabannya adalah 2, karena id yang dihasilkan WordPress untuk
$sender1
dan$sender2
berbeda.Hal yang sama terjadi dalam kasus ini:
Di atas saya menggunakan fungsi
sent_to_grandma
di dalam closure, dan bahkan jika kodenya identik, 2 closure adalah 2 instance\Closure
objek yang berbeda , jadi WP akan membuat 2 id yang berbeda, yang akan menyebabkan action ditambahkan dua kali, walaupun prioritasnya sama.sumber
Anda tidak dapat menambahkan tindakan yang sama ke kait tindakan yang sama , dengan prioritas yang sama .
Hal ini dilakukan untuk mencegah beberapa plugin mengandalkan tindakan pihak ketiga plugin terjadi lebih dari satu kali (pikirkan woocommerce dan semua plugin pihak ketiga, seperti integrasi pembayaran gateway, dll). Jadi tanpa menentukan prioritas, Nenek tetap miskin:
Namun, jika Anda menambahkan prioritas pada tindakan tersebut:
Nenek sekarang meninggal dengan $ 4 di sakunya (1, 2, 3 dan default: 10).
sumber