Перед окончательным релизом symfony 1.1 (который должен произойти уже на этой неделе), Разработчики расказали о новой архитектуре symfony 1.1. Кроме уже существующих новых возможностей, новая версия - это год сложной работы по внутренней перестройке фреймворка. Итак давайте покапаемся во внутренностях!
Платформа symfony (the symfony platform)
symfony 1.1 основана на множестве сплоченных, но отдельных классах - symfony platform:
Каждый класс в symfony platform можно использовать без общей MVC (Модель Вид Контроллер) архитектуры. Классы в symfony platform не имеют зависимостей, только одно условие требуется для их использования - это предварительная регистрация в symfony autoloader:
require_once '/path/to/sfCoreAutoload.class.php';
sfCoreAutoload::register();
Написав всего пару строк, вы можете использовать любой класс из symfony platform. К примеру если один из ваших проектов не использует symfony, вы все равно можете использовать класс sfYaml просто подключив symfony autoloader:
require_once '/path/to/sfCoreAutoload.class.php';
sfCoreAutoload::register();// load some YAML file or string
$config = sfYaml::load('/path/to/a/file.yml');
$config = sfYaml::load(<<<EOF
config:
key: value
foo: [bar, foobar]
bar: { bar: foo }
EOF);// dump some array to YAML
$yaml = sfYaml::dump($config);
То же самое касается всех классов, к примеру класс sfCache:
require_once '/path/to/sfCoreAutoload.class.php';
sfCoreAutoload::register();$cache = new sfSQLiteCache(array('database' => dirname(__FILE__).'/cache.db'));
$cache->set('foo', 'bar');
$value = $cache->get('foo');
В примерах используется SQLite backend, но symfony таже предоставляется backends основанные на File, APC, XCache, EACcelerator, и Memcache.
Даже если использование независимых классов кажется естественным, symfony platform пошла на шаг дальше с такими классами как sfRequest или sfResponse. Посмотрим пример где используются эти два класса для создания простого скрипта ‘Hello World’:
require_once '/path/to/sfCoreAutoload.class.php';
sfCoreAutoload::register();
$dispatcher = new sfEventDispatcher();$request = new sfWebRequest($dispatcher);
$response = new sfWebResponse($dispatcher);$content = 'Hello '.$request->getParameter('name', 'World');$response->setContent($content);
$response->send();
В этом примере мы используем объект sfEventDispatcher. Даже если классы в платформе полностью разделены, некоторые классы могут общаться друг с другом благодаря диспечеру (dispatcher). Диспечер (dispatcher) преставляет средства для уведомления и прослушивания событий. Вам не нужно создавать интерфейс для прослушивания, и использовать какой-либо специальный класс для создания события; событие определяется только по его имении и массивом параметров отправленых уведомителем (notifier).
К примеру, класс sfPatternRouting прослушивает события request.filter_parameters:
$callback = array($this, 'filterParameters');
$dispatcher->connect('request.filter_parameters', $callback);
И когда зпрос создан, sfWebRequest уведомляет событие request.filter_parameters:
$event = new sfEvent($this, 'request.filter_parameters');
$parameters = $dispatcher->filter($event, $parameters);
Итак, даже если классы sfWebRequest и sfPatternRouting разделены, они автомотичеки общаются друг с другом, когда они разделяют общий диспечер (dispatcher).
Чтоб представить эту возможность, изменим чуток в предыдущем примере, добавим объект роутинга (routing object), который подключается к приложению ‘Hello World’ по шабону /hello/:name:
require_once '/path/to/sfCoreAutoload.class.php';
sfCoreAutoload::register();$dispatcher = new sfEventDispatcher();$routing = new sfPatternRouting($dispatcher);
$routing->connect('hello', '/hello/name');$request = new sfWebRequest($dispatcher);
$response = new sfWebResponse($dispatcher);$content = 'Hello '.$request->getParameter('name', 'World');$response->setContent($content);
$response->send();
Теперь, если вы сохраните этот скрипт как index.php в root папке вашего веб сервера, вы можете увидеть работу приложения набрав в браузе, к примеру /index.php/hello/451fahrenheit.
Это хорошо если вы хотите использовать некоторые интересные функции, которые предлагает symfony, без использования всей MVC архитектуры.
Это так же прекрасный способ перевести ваше старое приложение на symfony. Вместо того, чтоб переписывать все с нуля, вы можете ввести концепцию symfony один раз.
Вы так же можете создать свой собственных фреймворк основаный на symfony platform. Вам не нужно выдумывать колесо, symfony platform все что вам нужно для создания классного фреймворка:
- sfRequest/sfRouting: Запросы
- sfUser/sfStorage: Пользователь/Сессии
- sfForm: Фреймворк для создания форм
- sfCache: Работа с кешем
- sfOutputEscaper: Защита от XSS атак
- sfResponse: Ответы
- …
Конечно, symfony framework сам основан на symfony platform:
Класс sfConfiguration предлагает способ для конфигурирования и настройки вашего приложения. Класс sfContext действует как регистр который хранит ссылки на все объекты ядра. И благодаря конфигурационному файлу factories.yml, вы очень легко можете настраивать все зарегистрированные классы, всего лишь отредактировав YAML файл.
Symfony MVC framework предлагает ряд дополнительных классов на вершине symfony framework, как показно ниже:
Слой Модели (Model layer) предствален сторонними библиотеками, Propel или Doctrine. Даже если symfony 1.1 связана с плагином Propel, нет ничего проще перейти на Doctrine, установив sfDoctrinePlugin. Обе ORMs предлагают одинаковый уровень интеграции с symfony.
Слой Вид (View layer) представлен классом sfView , набором хелперов (helpers), и шаболнами (templates) разработчика.
Слой Контроллер (Controller layer) основан на цепочке фильтров (filter chine) и действий (actions) определенных разработчиком.
Начиная с версии 1.1, symfony одним из наиболее разделенных фреймворков существующих на PHP, даже болше чем Zend Framework. К примеру, sfForm фреймворк используется без любых классов MVC в отличии от Zend_Form который несколько привязан к слоям контроллер и вид (controller and view layers).