Простая система плагинов на PHP своими руками

Это ну практически максимально простой способ создания системы плагинов на основе хуков (hook) которую я смог придумать минут за пять. Для её полноценности её нужно ещё нормально доработать, но делать этого мы конечно же не будем. Однако в таком виде она тоже функционирует, это не совсем обычная концепция.

Мысль такая:
1. Создаём и подключаем класс, в который собираем все хуки и функции к ним закреплённые
2. Создаем в этом классе функцию при вызове которой вытаскивает все подвешенные хуки и запускает функции привязанные к ним
3. Вставляем куда надо вызов второй функции
4. Создаём плагины в которых накидываем функции на хуки
5. ???
6. Готово


Нам пригодится такая структура:
index.php
include
-- hook.class.php
plugins
-- test
-- -- plugin.php

Для начала откроем и опишем include/hook.class.php:

<?php

class PM {

	private static $hooks = array(); //Массив, в котором будут находиться все хуки
	
	public static function Hook($hookName, $function) { //функция, которая собирает хуки в кучу
		self::$hooks[$hookName][] = $function; //записываем имя функции в отдельную ячейку для определённого хука
	}
	
	public static function runHook($hookName, &$variable = false) { //функция, которая будет запускать все функции прицепленные определённым хуком
		if (isset(self::$hooks[$hookName])) { //проверяем, есть ли такой хук воще
			
			foreach (self::$hooks[$hookName] as $f) { //начинаем пробегаться по всему что к этому хуку прикреплено
				if ($variable != false) { //Если хук с параметром, тогда
					call_user_func_array($f, array(&$variable));
				} else { //Иначе мы просто так её запускаем
					call_user_func($f);
				} //if
			} //foreach
		} //if
	} //function runHook
}

Теперь index.php:

<?php
	require_once("include/hook.class.php"); //Инклюдим класс с функциями хуков

	$menu_items = array( //Допустим у нас есть массив меню
		100 => ['Главная', 'http://evilcoder.ru'],
		200 => ['Не главная','http://evilcoder.ru']
	);
	PM::runHook('menu', $menu_items); //Вешаем хук на переменную $menu_items
	PM::runHook('info'); //Вешаем просто так хук, чтобы что-нибудь сюда выполнить
	
	foreach ($menu_items as $item) {
		echo "<p><a href='$item[1]'>$item[0]</a></p>";
	}

По идее уже всё готово, наша примитивная система на хуках уже работает. При запуске мы увидим, как всё сейчас выглядит с пустыми хуками.

Ну наверное теперь нужно проверить как это всё работает, поэтому я изначально попросил создать папку plugins с плагином test внутри.
Откроем plugins/test/plugin.php и заполним чем-нибудь:

<?php

	function test(&$menu) { //функция которая добавит пунктов в меню
		$menu[300] = ['Плагин','http://evilcoder.ru']; 
		$menu[400] = ['Пункт меню через плагин test','http://evilcoder.ru']; 
	}
	
	PM::Hook('menu', 'test'); //Прикрепляем к хуку функцию test
	
	function info() { //Функция info которая без параметров. Сюда можно всякой разной дичи добавить
		global $info; //Можно например подцепиться к переменным которые находятся в той же области видимости как и runHook
		$info = 'Это из функции info на хуке info '; //Изменим ту самую переменную которая находится возле run
		echo "Тут какая-нибудь информация"; //Просто сделаем echo, почему бы и нет
	}
	
	PM::Hook('info', 'info'); //Цепляем функцию info к хуку info

	function style() { //добавим ещё функцию style к хуку info
		echo "<style>p > a{ font-size: 25px; color: #215289; }</style>";
	}
	
	PM::Hook('info', 'style'); //прицепим её так же к хуку 

Ну и под конец модифицируем index.php до такого состояния:

<?php
	require_once("include/hook.class.php"); 
	require_once("plugins/test/plugin.php"); //Заинклюдим ещё сам плагин
	$menu_items = array( 
		100 => ['Главная', 'http://evilcoder.ru'],
		200 => ['Не главная','http://evilcoder.ru']
	);
	$info = ''; //Создадим пустое $info
	PM::runHook('menu', $menu_items); 
	PM::runHook('info'); //Вешаем просто так хук, чтобы что-нибудь сюда выполнить
	
	echo $info; //Выведем $info
	
	foreach ($menu_items as $item) {
		echo "<p><a href='$item[1]'>$item[0]</a></p>";
	}

Ну и в итоге видим примерно такую картинку

Стили накинулись (хотя так делать со стилями неправильно, это только для теста), переменная изменилась, пункт в меню добавился, echo отпечатало
Вопросы, пожелания и всё такое Вы можете оставить прямо в комментах под статьей )