Подтвердить что ты не робот

Внедрение передового опыта PHP Event-Listener

Я пытаюсь создать CMS-подобную систему в PHP. делая его максимально модульным и расширяемым.

Может ли кто-нибудь предложить мне лучший сценарий создания системы event-listener в PHP (например, очень упрощенная версия системы Drupal), создание крючков и их реализация в кратком примере также будет приятным.

4b9b3361

Ответ 1

Ну, действительно есть три разных способа сделать это с точки зрения реализации (обратите внимание, что это шаблоны проектирования OO, но вы могли бы реализовать их функционально или процедурно, если бы захотели).

1. Шаблон наблюдателя

Вы можете реализовать шаблон наблюдателя. В принципе, у вас есть все, что может поднять события. Затем классы/код, который вы хотите прослушать, привязывают к тому, что он хочет прослушать. Итак, скажем, у вас есть контроллер под названием Foo. Если вы хотите прослушать его, вы можете позвонить $fooController->attach($observer);. Затем, когда контроллер хотел что-то сказать, он отправил событие всем наблюдателям.

Это действительно хорошо подходит для системы уведомлений (для расширения классов). Это не так хорошо подходит для изменения поведения кода в реальном времени.

2. Рисунок декоратора Вы также можете реализовать Decorator Pattern. В принципе, вы берете объект, который хотите изменить, и "оберните" его в новый объект, который делает то, что вы хотите изменить. Это действительно хорошо подходит для изменения и расширения поведения (поскольку вы можете выборочно переопределять функциональность из упакованного класса).

Это работает очень хорошо, если вы определили интерфейсы и ожидаете, что объекты будут соответствовать им. Если у вас нет интерфейсов (или не используйте их правильно), большая часть того, что может сделать для вас шаблон декоратора, будет потеряна.

Также обратите внимание, что это действительно не способ делать события, это способ изменения поведения объекта.

3. Посредник

Вы также можете использовать Mediator. В принципе, у вас будет один глобальный посредник, который отслеживает ваших слушателей. Когда вы хотите инициировать событие, вы отправляете событие посреднику. Затем медиатор может отслеживать, какие объекты прослушивания хотят получить это событие, и правильно передать сообщение.

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

Я расширил эту тему в сообщении в блоге.

Ответ 2

Нашел это, очень просто и очень хорошо.

/*
 Example 1: 
 event::bind('blog.post.create', function($args = array())
 {
    mail('[email protected]', 'Blog Post Published', $args['name'] . ' has been published');
});

 Example 2: 
 event::trigger('blog.post.create', $postInfo);
*/

class event
{
    public static $events = array();

    public static function trigger($event, $args = array())
    {
        if(isset(self::$events[$event]))
        {
            foreach(self::$events[$event] as $func)
            {
                call_user_func($func, $args);
            }
        }

    }

    public static function bind($event, Closure $func)
    {
        self::$events[$event][] = $func;
    }
}

Ответ 3

Вот как я это сделал в нескольких проектах

Все объекты создаются с помощью функции-конструктора вместо оператора new.

 $obj = _new('SomeClass', $x, $y); // instead of $obj = new SomeClass($x, $y);

у этого есть много преимуществ по сравнению с raw new, с точки зрения обработки событий важно, чтобы _new() поддерживал список всех созданных объектов.

Также существует глобальная функция send($message, $params), которая выполняет итерацию, хотя этот список, и, если объект предоставляет метод "on_ $message", вызывает этот метод, передавая параметры:

function send() {
    $_ = func_get_args();
    $m = "on_" . array_shift($_);
    foreach($_all_objects as $obj)
        if(method_exists($obj, $m))
            call_user_func_array(array($obj, $m), $_);
}

Итак, например, send('load') вызовет метод on_load для каждого объекта, который он определил.

Ответ 4

Если вы используете PHP 5.3 (и, следовательно, имеете доступ к богатым закрытиям), система событий/фильтров в Lithium - это то, что Я бы использовал в качестве основы для AOP в PHP.

Ответ 5

Не знаю, почему люди в PHP думают, что они получают что-то от Слушателей. Простой вопрос: если я ищу PHP-разработчиков, я просто задаю один вопрос: каковы проблемы и ограничения MVC?

Если вы не можете ответить на этот вопрос, вы не должны смотреть на внедрение слушателей или, в этом случае, реализацию фреймворка.

Далее Знай свой язык. PHP - это однопоточный, однострочный. Значение памяти и объектов зависит от потока. В результате слушатели и другие объекты останутся живыми в Java/С# никогда не должны использоваться в php, поскольку они, как правило, дорого стоят, чтобы создавать и усложнять приложение, не получая достаточного значения, чтобы оправдать их.

Рамки НЕ поддерживаются, и по состоянию на 2 года назад руководство по PHP говорит, что они не намерены поддерживать Framework для PHP. Это означает, что для того, чтобы заставить фреймворк работать наполовину так же хорошо, как собственный PHP с PEAR, вам нужно реализовать десятки дополнений, которые занимают память, затрудняют разработку и обфускацию кода без каких-либо преимуществ.

Стандартная разработка PHP быстрее и проще в использовании, чем в большинстве фреймворков для PHP. Существует несколько библиотек PEAR, которые могут помочь вам в вашей задаче. Не пытайтесь быть многопоточным разработчиком в однопоточной системе, это сервер не является реальным значением.

Если вам нужна межпоточная связь, отбросьте PHP и разработайте на многопоточном языке.

Не используйте технологию из-за слова BUZZ. MVC чрезмерно используется и в 99% случаев используется неправильно. Результат варьируется от медленных систем до плохих структур данных/проверки. Слушатели одинаковы, знаете, что это, прежде чем использовать его.

Первый вопрос перед тем, как я? Должно быть, почему я должен? Знайте свою технологию, тренды учат вредным привычкам и дрянным разработчикам.

Извините, soapbox закончился, просто надоело запускать на работу программистов PHP, которые попугаи консервируют ответы и идеологии, не задумываясь о них. Вот почему разработчики Java высмеивают PHP-разработчиков, потому что они пытаются использовать технологию, для которой язык не предназначен, и создатель сказал, что он не намерен поддерживать.

Есть отличные разработчики PHP, а не те, кто пытается использовать жесткие рамки, такие как Zend Framework, или такие технологии, как контроллеры домена или прослушиватели.