Zaczynam nową aplikację internetową w PHP i tym razem chcę stworzyć coś, co ludzie mogą rozszerzyć za pomocą interfejsu wtyczki.
W jaki sposób można napisać „haki” w kodzie, aby wtyczki mogły dołączać się do określonych zdarzeń?
źródło
Zaczynam nową aplikację internetową w PHP i tym razem chcę stworzyć coś, co ludzie mogą rozszerzyć za pomocą interfejsu wtyczki.
W jaki sposób można napisać „haki” w kodzie, aby wtyczki mogły dołączać się do określonych zdarzeń?
Możesz użyć wzorca Observer. Prosty funkcjonalny sposób na osiągnięcie tego:
<?php
/** Plugin system **/
$listeners = array();
/* Create an entry point for plugins */
function hook() {
global $listeners;
$num_args = func_num_args();
$args = func_get_args();
if($num_args < 2)
trigger_error("Insufficient arguments", E_USER_ERROR);
// Hook name should always be first argument
$hook_name = array_shift($args);
if(!isset($listeners[$hook_name]))
return; // No plugins have registered this hook
foreach($listeners[$hook_name] as $func) {
$args = $func($args);
}
return $args;
}
/* Attach a function to a hook */
function add_listener($hook, $function_name) {
global $listeners;
$listeners[$hook][] = $function_name;
}
/////////////////////////
/** Sample Plugin **/
add_listener('a_b', 'my_plugin_func1');
add_listener('str', 'my_plugin_func2');
function my_plugin_func1($args) {
return array(4, 5);
}
function my_plugin_func2($args) {
return str_replace('sample', 'CRAZY', $args[0]);
}
/////////////////////////
/** Sample Application **/
$a = 1;
$b = 2;
list($a, $b) = hook('a_b', $a, $b);
$str = "This is my sample application\n";
$str .= "$a + $b = ".($a+$b)."\n";
$str .= "$a * $b = ".($a*$b)."\n";
$str = hook('str', $str);
echo $str;
?>
Wynik:
This is my CRAZY application
4 + 5 = 9
4 * 5 = 20
Uwagi:
W tym przykładowym kodzie źródłowym musisz zadeklarować wszystkie swoje wtyczki przed rzeczywistym kodem źródłowym, który chcesz rozszerzyć. Podałem przykład obsługi pojedynczej lub wielu wartości przekazywanych do wtyczki. Najtrudniejszą częścią tego jest napisanie faktycznej dokumentacji, która zawiera listę argumentów przekazywanych do każdego haka.
To tylko jedna metoda na stworzenie systemu wtyczek w PHP. Są lepsze alternatywy, sugeruję zapoznać się z Dokumentacją WordPress, aby uzyskać więcej informacji.
Mediator Pattern
. Prawdziwi obserwatorzy są wyłącznie powiadomieniami, nie ma przekazywania wiadomości ani powiadomień warunkowych (nie ma też centralnego menedżera do kontrolowania powiadomień). Nie powoduje to, że odpowiedź jest zła , ale należy zauważyć, aby ludzie nie nazywali rzeczy złym imieniem ...Powiedzmy, że nie chcesz wzorca Observer, ponieważ wymaga to zmiany metod klas, aby obsłużyć zadanie nasłuchiwania, i chcesz czegoś ogólnego. Powiedzmy, że nie chcesz używać
extends
dziedziczenia, ponieważ możesz już dziedziczyć w swojej klasie od innej klasy. Czy nie byłoby wspaniale mieć ogólny sposób na podłączenie dowolnej klasy bez większego wysiłku ? Oto jak:W części pierwszej możesz zawrzeć
require_once()
wywołanie u góry skryptu PHP. Ładuje klasy, aby coś można podłączyć.W części 2 właśnie tam ładujemy klasę. Uwaga: Nie musiałem robić nic specjalnego w klasie, co znacznie różni się od wzorca Obserwatora.
W części 3, gdzie zamieniamy naszą klasę na „wtykową” (to znaczy obsługuje wtyczki, które pozwalają nam przesłonić metody klasowe i właściwości). Na przykład, jeśli masz aplikację internetową, możesz mieć rejestr wtyczek i możesz tutaj aktywować wtyczki. Zwróć także uwagę na
Dog_bark_beforeEvent()
funkcję. Jeśli$mixed = 'BLOCK_EVENT'
ustawię przed instrukcją return, zablokuje to szczekanie psa, a także zablokuje Dog_bark_afterEvent, ponieważ nie będzie żadnego zdarzenia.W części 4 jest to normalny kod działania, ale zauważ, że to, co według ciebie mogłoby się uruchomić, wcale tak nie działa. Na przykład pies nie ogłasza swojej nazwy „Fido”, ale „Coco”. Pies nie mówi „miau”, ale „hau”. A kiedy później chcesz zobaczyć imię psa, okazuje się, że jest to „Różne” zamiast „Coco”. Wszystkie te zastąpienia podano w części 3.
Jak to działa? Cóż, wykluczmy
eval()
(który wszyscy mówią, że jest „zły”) i wykluczymy, że nie jest to wzorzec Obserwatora. Tak więc działa to podstępna pusta klasa o nazwie Pluggable, która nie zawiera metod i właściwości używanych przez klasę Dog. Ponieważ tak się dzieje, magiczne metody zaangażują się dla nas. Dlatego w częściach 3 i 4 rozmawiamy z obiektem pochodzącym z klasy wtykowej, a nie z samą klasą Dog. Zamiast tego pozwalamy klasie Plugin wykonać dla nas „dotykanie” obiektu Dog. (Jeśli to jakiś wzorzec projektowy, o którym nie wiem - daj mi znać.)źródło
Hak i słuchacz metoda jest najbardziej powszechnie używane, ale są jeszcze inne rzeczy, które możesz zrobić. W zależności od wielkości aplikacji i tego, komu pozwolisz zobaczyć kod (czy to będzie skrypt FOSS, czy coś w domu), będzie to miało duży wpływ na to, jak chcesz zezwolić na wtyczki.
kdeloach ma dobry przykład, ale jego implementacja i funkcja przechwytywania jest trochę niebezpieczna. Poprosiłbym cię o podanie więcej informacji na temat natury aplikacji php podczas pisania oraz o tym, jak widzisz odpowiednie wtyczki.
+1 do kdeloach ode mnie.
źródło
Oto podejście, którego użyłem, to próba skopiowania z mechanizmu sygnałów / szczelin Qt, rodzaj wzorca obserwatora. Obiekty mogą emitować sygnały. Każdy sygnał ma identyfikator w systemie - składa się z identyfikatora nadawcy + nazwy obiektu Każdy sygnał można powiązać z odbiornikami, co jest po prostu „wywoływalne”. Korzystasz z klasy magistrali, aby przekazywać sygnały wszystkim zainteresowanym ich otrzymaniem. zdarza się, że „wysyłasz” sygnał. Poniżej znajduje się przykładowa implementacja
źródło
Uważam, że najłatwiejszym sposobem byłoby postępowanie według własnych rad Jeffa i rozejrzenie się po istniejącym kodzie. Spróbuj spojrzeć na Wordpress, Drupal, Joomla i inne dobrze znane CMS-y oparte na PHP, aby zobaczyć, jak wyglądają i działają ich zaczepy API. W ten sposób możesz nawet uzyskać pomysły, o których wcześniej nawet nie myślałeś, aby uczynić z nich coś więcej.
Bardziej bezpośrednią odpowiedzią byłoby zapisanie ogólnych plików, które „włączają_once” do swojego pliku, co zapewni użyteczność, której będą potrzebować. Zostałoby to podzielone na kategorie i NIE zapewnione w jednym MASYWNYM pliku „hooks.php”. Bądź jednak ostrożny, ponieważ w rezultacie dołączane do nich pliki mają coraz więcej zależności i poprawia funkcjonalność. Staraj się utrzymywać niskie zależności API. IE mniej plików, aby je uwzględnić.
źródło
Jest fajny projekt o nazwie Stickleback autorstwa Matta Zandstry w Yahoo, który zajmuje się znaczną częścią pracy z wtyczkami w PHP.
Wymusza interfejs klasy wtyczek, obsługuje interfejs wiersza poleceń i nie jest zbyt trudny do uruchomienia i uruchomienia - szczególnie jeśli przeczytasz o tym okładkę w magazynie dla architektów PHP .
źródło
Dobra rada to przyjrzeć się, jak to zrobiły inne projekty. Wielu wzywa do zainstalowania wtyczek i zarejestrowania ich „nazwy” dla usług (tak jak robi to Wordpress), więc masz „punkty” w kodzie, w których wywołujesz funkcję, która identyfikuje zarejestrowanych słuchaczy i wykonuje je. Standardowym wzorcem projektowym OO jest wzorzec obserwatora , który byłby dobrą opcją do wdrożenia w prawdziwie obiektowym systemie PHP.
Zend Framework umożliwia korzystanie z wielu metod zahaczających i jest bardzo ładnie architekturę. To byłby dobry system do obejrzenia.
źródło
Dziwię się, że większość odpowiedzi tutaj wydaje się dotyczyć wtyczek lokalnych dla aplikacji WWW, tj. Wtyczek działających na lokalnym serwerze WWW.
A jeśli chcesz, aby wtyczki działały na innym - zdalnym - serwerze? Najlepszym sposobem na to byłoby udostępnienie formularza, który pozwala zdefiniować różne adresy URL, które będą wywoływane, gdy wystąpią określone zdarzenia w aplikacji.
Różne zdarzenia wysyłałyby różne informacje na podstawie zdarzenia, które właśnie miało miejsce.
W ten sposób po prostu wykonasz wywołanie cURL na adres URL, który został podany twojej aplikacji (np. Przez https), gdzie zdalne serwery mogą wykonywać zadania w oparciu o informacje wysłane przez twoją aplikację.
Zapewnia to dwie korzyści:
źródło