Hypothetisches Beispiel, aber reale Anwendbarkeit (für jemanden, der lernt, wie ich).
Gegeben diesen Code:
<?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, jetzt rufe ich meine WP-Site auf und melde mich an. Ich überquere einige Seiten in Admin. Die Aktion 'init' wird insgesamt 100 mal ausgelöst, bevor der Akku meines Laptops leer ist.
Erste Fragen: Wie viel Geld haben wir an Oma geschickt? Ist es 1 $, 2 $, 100 $ oder 200 $ (oder etwas anderes?)
Wenn Sie auch Ihre Antwort erklären könnten, wäre das fantastisch.
Zweite Frage: Wenn wir sicherstellen möchten, dass wir nur Oma $ 1 schicken, wie geht das am besten? Globale Variable (Semaphor), die beim ersten Senden von $ 1 auf 'true' gesetzt wird? Oder gibt es einen anderen Test, um festzustellen, ob eine Aktion bereits stattgefunden hat und um zu verhindern, dass sie mehrmals ausgelöst wird?
Dritte Frage: Ist das etwas, worüber sich Plugin-Entwickler Sorgen machen? Mir ist klar, dass mein Beispiel albern ist, aber ich habe sowohl an Leistungsprobleme als auch an andere unerwartete Nebenwirkungen gedacht (z. B. wenn die Funktion in der Datenbank aktualisiert / eingefügt wird).
Antworten:
Hier sind einige zufällige Gedanken dazu:
Frage 1
Für 100 Seiten haben wir ihr 100 x $ 1 = $ 100 geschickt.
Hier meinen wir eigentlich
100 x do_action( 'init' )
Anrufe.Es war egal, dass wir es zweimal hinzugefügt haben mit:
weil die Rückrufe und Prioritäten (Standard 10) identisch sind .
Wir können überprüfen, wie das
add_action
nur ein Wrapper füradd_filter
das globale$wp_filter
Array ist:Wenn wir jedoch die Priorität geändert haben:
Dann würden wir ihr 2 x 1 USD pro Seite oder 200 USD für 100 Seiten senden.
Dasselbe gilt, wenn die Rückrufe unterschiedlich waren:
Frage 2
Wenn wir es nur einmal pro Laden der Seite senden möchten, sollte dies folgendermaßen aussehen:
weil der
init
haken nur einmal abgefeuert wird. Möglicherweise gibt es andere Hooks, die pro Seitenladevorgang mehrmals ausgelöst werden.Lass uns anrufen:
aber was passiert, wenn
someaction
10 mal pro Seite gezündet wird?Wir könnten die
send_money_to_grandma()
Funktion mit anpassenoder verwenden Sie eine statische Variable als Zähler:
Wenn wir es nur einmal (je!) Ausführen möchten, registrieren wir möglicherweise eine Option in der
wp_options
Tabelle über die Options-API :Wenn wir ihr einmal täglich Geld senden möchten, können wir die Transient-API verwenden
oder auch den wp-cron benutzen.
Beachten Sie, dass Sie möglicherweise Ajax-Aufrufe haben. auch.
Es gibt Möglichkeiten, diese zu überprüfen, z. B. mit
DOING_AJAX
Es kann auch Umleitungen geben, die den Fluss unterbrechen können.
Dann könnten wir nur an das Backend zu beschränken,
is_admin()
oder nicht:! is_admin()
.Frage 3
ja das ist wichtig
Wenn wir unsere Oma sehr glücklich machen wollen, machen wir:
aber das wäre sehr schlecht für die leistung ... und unsere brieftasche ;-)
quelle
Dies ist eher ein Kommentar zur Antwort der sehr guten Birgire als eine vollständige Antwort, aber da sie Code schreiben muss, passen Kommentare nicht.
Aus der Antwort geht hervor, dass der einzige Grund, warum im OP-Beispielcode eine Aktion einmal hinzugefügt wird, selbst wenn
add_action()
sie zweimal aufgerufen wird, die Tatsache ist, dass dieselbe Priorität verwendet wird. Das ist nicht wahr.Im Code
add_filter
eines wichtigen Teils befindet sich ein_wp_filter_build_unique_id()
Funktionsaufruf, der pro Rückruf eine eindeutige ID erzeugt .Wenn Sie eine einfache Variable verwenden, z. B. eine Zeichenfolge, die einen Funktionsnamen enthält, entspricht
"send_money_to_grandma"
die ID der Zeichenfolge selbst. Wenn also die Priorität identisch ist und die ID identisch ist, wird der Rückruf einmal hinzugefügt.Es ist jedoch nicht immer so einfach. Callbacks können alles sein, was
callable
in PHP enthalten ist:Die ersten beiden werden jeweils durch eine Zeichenfolge und ein Array mit 2 Zeichenfolgen (
'send_money_to_grandma'
undarray('MoneySender', 'send_to_grandma')
) dargestellt, sodass die ID immer dieselbe ist und Sie sicher sein können, dass der Rückruf einmal hinzugefügt wird, wenn die Priorität dieselbe ist.In allen anderen 3 Fällen hängt die ID von Objektinstanzen ab (eine anonyme Funktion ist ein Objekt in PHP), sodass der Rückruf nur einmal hinzugefügt wird, wenn das Objekt dieselbe Instanz ist , und es wichtig ist, dieselbe Instanz und dieselbe Klasse zu notieren sind zwei verschiedene Dinge.
Nehmen Sie dieses Beispiel:
Wie viele Dollar senden wir pro Seite laden?
Antwort 2, weil die ID Wordpress erzeugt für
$sender1
und$sender2
sind unterschiedlich.Das gleiche passiert in diesem Fall:
Oben habe ich die Funktion
sent_to_grandma
innerhalb von Closures verwendet, und selbst wenn der Code identisch ist, sind die beiden Closures zwei unterschiedliche\Closure
Objektinstanzen. WP erstellt also zwei unterschiedliche IDs, wodurch die Aktion zweimal hinzugefügt wird, auch wenn die Priorität gleich ist.quelle
Sie können nicht das Hinzufügen gleiche Aktion auf die gleiche Aktion Haken , mit der gleichen Priorität .
Dies wird getan, um zu verhindern, dass mehrere Plugins, die sich auf die Aktion eines Drittanbieter-Plugins stützen, mehrmals ausgeführt werden (denken Sie an woocommerce und alle Plugins von Drittanbietern, wie Gateway-Zahlungsintegrationen usw.). Ohne Angabe der Priorität bleibt Oma also arm:
Wenn Sie diesen Aktionen jedoch Priorität hinzufügen, gilt Folgendes:
Oma stirbt jetzt mit 4 $ in der Tasche (1, 2, 3 und der Standard: 10).
quelle