1. Структурирование кода с помощью системы модулей
В PHP нет модулей и пространств имен. Поэтому мы реализовали собственную, простую в реализации, но гибкую в использовании систему модулей, которая помогает нам делать наш код структурированным и повторно используемым:
Core::load('IO.FS');
foreach (IO_FS::Dir('.') as $file)
IO::stderr()->format("%s %s\n", $file->name, $file->name->mtime->format('%d.%m.%Y %H:%M:%S'));
2. Максимальное использование ООП и динамических возможностей, предоставляемых пятой версией PHP
Мы широко используем перегрузку операций вызовы методов и доступа к обычным и индексированным свойствам объектов для построения программных интерфейсов в стиле DSL:
$config->
begin_db->
dsn('mysql://user:password@localhost/db')->
end->
begin_cache->
dsn('memcache://localhost')->
default_timeout(300)->
end->
begin_site->
begin_front->
top_limit(8)->
end->
end;
3. Легковесный ORM-модуль
Мы не используем паттерн ActiveRecord, вместо этого мы динамически строим иерархию объектов-мапперов:
$stories = $this->db->news->stories->
for_category($this->category)->
most_important(4)->
paginate_with($this->pager)->
select();
4. Интеграция с поисковым механизмом Sphinx
Sphinx великолепен. Мы реализовали простой и удобный API поверх стандартного:
foreach ($sphinx->
select($query)->
using('stories')->
resolve_with(Search_Sphinx_ORM::Resolver()->mappers($db->news->stories))
range(20) as $story)
printf('%d %s %s', $story->id, $story->pub_date->format('%d.%m.%Y'),
$story->body);
5. Простая система шаблонов, расширяющая стандартные возможности шаблонизатора PHP
Поддерживаются вложенные шаблоны с собственными пространствами имен параметров, частичные шаблоны (partials), классы с helper-методами:
return Templates_HTML::Template('site/news')->
with(array(
'stories' => $stories,
'pager' => $pager))->
inside(Templates_HTML::Template('site')->
with('top_menu', 'news'));
6. Модульная структура приложений
Выполнение запроса реализуется цепочкой стандартных обработчиков:
WS::Runner()->run(
WS_DSL::status(array(404, 500),
WS_DSL::config('../etc/config.php',
WS_DSL::cache(
WS_DSL::orm(App::db(),
WS_DSL::session(
WS_DSL::auth_session($db, $application)))))));
7. REST-архитектура приложений
Приложение представляет собой набор классов ресурсов и описывается внутренним DSL, основанным на модели JAX-RS:
WS_REST::Application()->
begin_resource('news', 'App.News.Index', 'news')->
sublocator('stories')->sublocator('categories')->
index()->
end->
begin_resource('stories', 'App.News.Stories.Index',null)->
sublocator('story', '{id:\d+}')-> get('draft')->
post()->
index()->
end->
begin_resource('story', 'App.News.Stories.Story', null)->
sublocator('files')->
put('publish')->
put('archivate')->
get('preview')->
delete()->
put()->
index()->
end;
8. Интеграция с внешними сервисами
Service_Google_Chart::pie('700x300')->
title('Stories by category')->
data_from($data, 'n')->
legend_from($data, 'n')->
labels_from($data, 'title')->
colors('ff2c00')->
save_as('categories-popularity.png');
Реализованы: Google Finance, Google Data, Google Analytics, Recaptcha, Yahoo Weather.
9. Инструменты разработчика
Мы не используем phpdoc и doxygen. Мы используем собственный стандарт документирования на основе XML. С его помощью, например, мы строим диаграммы, помогающие нам проектировать код:
Наши инструменты помогают нам генерировать документацию, проверять код на правильность оформления, управлять обновлениями баз данных.



