Convention over Configuration
Пришел к убеждению, что надо снижать требования к конфигурированию приложения. В итоге переделал систему событий. Ядро перекроил, дема publicate временно от него отстала и не будет работать. А вот мой Hello world:
Точка входа index.php
<?php
require '../../framework/qb.php';
Qb::init()->request()->end();
1. Как видите, применил технику fluent.
2. Теперь приложение способно работать вообще без файла конфигурации. Минимально необходимые действия будут выолнены по-умолчанию.
Класс приложения в файле {appDir}/protected/application.php:
<?php
class Application extends QbCustomComponent
{
public function request()
{
echo $this->baseUrl . "<br /><br />\n";
echo 'Hello world!';
return $this;
}
}
$this->baseUrl реально вызывает Qb::get('baseUrl')
return $this необходим для поддержки цепочек fluent (см. выше)
Этот код уже работает, но будем потихоньку усложнять.
События через магию
Теперь события могут происходить в любом компоненте, а не в глассе Qb. Реализовано через магический метод __call — когда мы обращаемся к методу $foo->bar() будут вызваны события
beforeBar, onBar и afterBar. С оговоркой: yfcnjzobq метод bar должен отсутствовать, иначе магия не сработает. Вместо него в классе компоненты мы можем описать onBar()
Снова заглянем в наш стартовый скрипт
Qb::init()->request()->end();
Ядро фреймворка в методе init выполняет некую начальную инициализация и возвращает ссылку на объект-приложение. У этого приложения мы по цепочке вызываем методы request и затем end. Вот на end мы и протестируем события. $app->end() будет вызван как при нормальном завершении, там и при аварийном после ошибки/неперехваченного исключения. Это хорошее место для обязательных действий в конце.
Мой новый механизм событий настроен так, что вместо отсутствующего реального end() будут по возможности вызываться события beforeEnd, onEnd, afterEnd.
Для простоты я описал обработчик в этом же классе. Можно было забиндить сторонние обработчики через $foo->wrap()
Перед окончанием работы выведем на страницу текст ошибок, если они были.
class Application extends QbCustomComponent
{
public function request()
{
1/0; // warning
echo $this->baseUrl . "<br /><br />\n";
echo 'Hello world!';
return $this;
}
public function beforeEnd()
{
$log = Qb::getLog(array(E_ERROR, E_WARNING));
foreach ($log as $l) {
list(, $message, $file, $line, , ) = $l[0];
echo '<p>' . ($l[2] == E_ERROR ? 'ERROR' : 'WARNING') . ' <em>"'
. $message . '"</em> in module <strong>' . basename($file, '.php')
. '</strong> line <strong>' . $line
. "</strong></p>\n";
}
}