Главная > Open Source, PHP, Разное > Симфония минимализму или красота в простоте — РНР фреймворк EpiCode

Симфония минимализму или красота в простоте — РНР фреймворк EpiCode

19 марта 2008

epicode.gifПриветствую наших читателей. Пока весь народ вокруг воздает честь и хвалу компании Zend за выход в виде релиза ее фреймворка Zend Framework 1.5, который, без преувеличения, конечно отличный инструмент для разработки и поддержки масштабных проектов, а другие спорят и превозносят каждый свое - Python или Django или RubyOnRails, третье обсуждают нюансы применения паттерна MVC (я бы сказал, архитектурной концепции) и даже ее применимости вообще к созданию веб-приложений на РНР, остальной мир... Да нет, все не так, конечно, впрочем судити сами.

Остальные же просто упрощают себе жизнь, причем самым кардинальным образом. Я не о тех, кто верстает статичные сайты на несколько страниц - им не нужны никакие фреймворки. А вот если нужно, с одной стороны, создать простую и гибкую систему, но вот всей мощи и идеологической нагрузки современных фреймворков им не нужно, по крайней мере сейчас и немедленно? Изучение и апробация в новом проекте каких-то сложных инструментов себя совершенно не оправдает, а в свете уже любимой многими концепции Getting Real даже чем-то вредно, но и городить свой велосипед как то уже не достойно...

Именно такая задача встала передо мной совершенно недавно, буквально на прошлой неделе. И я нашел выход. Совершенно простой, минимальный и простой, но функциональный ... нет, не фреймворк, а так, библиотечечку. Разобравшись, можно даже присвоить ей, пусть немного покривив душой, даже реализацию того самого паттерна MVC, хотя как он туда уместился и почему о такой простой вещи все говорят - никак не ясно. Эта маленькая и удивительная библиотека называется EpiCode. Что она может? Да, честно говоря, она почти ничего не делает, но то, что делает - делает на ура.

По сути - путем несложных манипуляций она на основе запрашиваемого пути (то есть, на основе информации об URL) отображает его на предварительно сконфигурированные методы обьектов. Это значит, что мы сначала делим наше приложение (вернее - можем поделить, хотя это и не догма) на некоторые обьекты или сущности. Для примера - сайт-каталог товаров может иметь несколько глобальных обьектов - User, Admin, Product, Catalog, Order.  Унифицируем обращение к этим обьектам, например, обозначаем, что при запросе URL вида domen.com/user мы будем взаимодействовать только с обьектом пользователь, а при работе с domen.com/catalog - это будет уже каталог товаров. Это первый шаг к построению простой но эффективной архитектуры нашего проекта.

Далее мы определим основные действия над обьектами, которые в дальнейшем будут реализованы как методы соответствующих классов. Да, для эффективного использования EpiCode необходимо строить приложение на основе обьектов, хотя их применение достаточно тривиальное - они просто логически группируют методы. Но ничего не мешает разделить структуру приложения - несколько или пусть даже один корневой обьект у нас отвечает за работу с запросами, а вся бизнес-логика традиционно реализуется в виде обьектов и/или обычными функциями в подключаемых файлах.

Допустим, у нашей сущности User будут следующие методы (кстати, в терминологии по ZendFramework аналогами будут Actions и роутеры - о них чуть позже) - Auth (отвечает за аутентификацию пользователя), New (создание нового пользователя, Edit (редактирование аккаунта), Profile (показывает профайл), Logout (выход). Кстати, можно вполне дробление производить и дальше, в некоторых модулях оно необходимо, для примера - для действия Edit над аккаунтом пользователя нужно определить еще и пару методов - Save для сохранения, Validate для проверки верности, Restore для отката недавно сделанных изменений, Default для установки поля в значение по умолчанию.

И теперь почти последнее - мы отобразим нашу цепочку в глобальной переменной-массиве $_, которая является служебной для библиотеки EpiCode и содержит те самые правила отображения запрашиваемых URL и обьектов и методов, куда мы их направляем - помните про роутеры из описания ZendFramework - здесь они возведены в минимализм. Это просто массив, который на каждый URL содержит два элемента, имя обьекта и имя метода, на который он отображается.

Кстати, одно ограничение есть - вы должны обьявить свои методы как static public, потому что EpiCode ничего не знает про создание ваших обьектов, а в основе лежит PHP функция call_user_funct, которая может вызвать только статические методы. Но это ограничение никак не существенное, ведь всегда можно вынести эти методы в отдельный слой обьектов, которые будут инкапсулировать верхний уровень обработки, всю остальную логику реализовать традиционно.

Возвращаясь к нашему примеру, у нас будут следующие пути:

domain.com/user/auth

domain.com/user/profile

domain.com/user/edit/save

Разберетесь о назначении каждого из них?   Вполне. А в служебной таблице роутинга это будет выглядеть следующим образом:

$_['routes']  = array('user/profile' => array('User_Object', 'User_Profile_View'));

Для примера я взял второй путь - мы сопоставили адрес вида user/profile статической функции  User_Profile_View обьекта User_Object. Все. Внутри этой функции вам доступно все - все глобальные переменные, переданные на сервер, $_REQUEST/$_GET/$_POST и все остальное, на вывод также не накладывается никаких ограничений. Можно использовать ваш любимый шаблонизатор, компоненты доступа к базам данных и все, что только нужно, можно и необходимо. Библиотека лишь предлагает вам быстро и четко структурировать доступ к функциональности вашего приложения, оставляя всю реализацию вам. Это, в принципе, и есть ее самое большое преимущество - она не ограничивает вас, вместе с тем беря на себя невидимую но полезную работу, позволяя сконцентрироваться на своем.

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

А как обработать заранее неизвестный путь, спросите вы? Да очень просто! EpiCode работает по принципу наименьшего общего, поэтому если у вас обьявлен обработчик на путь /user/profile, а пользователь вызовет адрес /user/profile/vasja, то в реальности обработка такого пути будет передана все тому же обработчику. Внутри вы можете проверять переменную __routes__, разбирая путь и определяя таким образом дополнительные параметры, создав просто один общий обработчик, а пользователям позволяя везде ссылаться на свой профайл полной ссылкой.

Конечно, я полностью осознаю, что эта библиотека ну никак не ровня реальным фреймворкам, и обеспечиваемый функционал также может быть расширен (например, передача параметров не через глобальные массивы, а параметрами методов-обработчиков, передача неразобранной части пути как параметров, оптимизация производительности для больших таблиц роутинга путем кеширования в память и т.п.), но поверьте, очень часто этого всего и не требуется. Даже с текущим функционалом для того, чтобы набросать основной скелет с заглушками на месте будущих реальных обработчиков, понадобится от силы пару часов или день - и в результате вы уже будете иметь мало-мальски функционирующий прототип, который в дальнейшем можно расширять и дополнять.   Поэтому, начиная следующий проект, посмотрите и спросите себя - а может его сделать максимально просто? А может, еще проще? Настолько просто, насколько возможно...?

P.S. Официальная страница проекта, примеры и дистрибутив для загрузки.

  1. 20 марта 2008 в 15:10 | #1

    интересно интересно.. надо будет покопаться в епикоде. спасибо за детальный разбор темы!

  2. jMas
    31 марта 2008 в 23:49 | #2

    Пришлите пожалуйста код на почту, указанную в этом сообщении. Буду признателен, т.к. архива на офф сайте по техническим причинам нет(

  3. 31 марта 2008 в 23:57 | #3

    нда, какие-то проблемы, выслал.

Комментирование отключено.
Developers.org.ua