developer blog

451 degrees Fahrenheit

Archives Posts

Архитектура symfony 1.1

June 24th, 2008 by pilot

 

Перед окончательным релизом symfony 1.1 (который должен произойти уже на этой неделе), Разработчики расказали о новой архитектуре symfony 1.1. Кроме уже существующих новых возможностей, новая версия - это год сложной работы по внутренней перестройке фреймворка. Итак давайте покапаемся во внутренностях!

Платформа symfony (the symfony platform)

symfony 1.1 основана на множестве сплоченных, но отдельных классах - symfony platform:

The 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:

The symfony MVC framework

Класс sfConfiguration предлагает способ для конфигурирования и настройки вашего приложения. Класс sfContext  действует как регистр который хранит ссылки на все объекты ядра. И благодаря конфигурационному файлу factories.yml, вы очень легко можете настраивать все зарегистрированные классы, всего лишь  отредактировав YAML файл.

Symfony MVC framework предлагает ряд дополнительных классов на вершине symfony framework, как показно ниже:

The symfony MVC 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).

Filed under Symfony, php having 1 Comment »

Archives Posts

Свершилось! Первые части книги "Формы и Действия в Symfony" доступны online

June 18th, 2008 by pilot

Я думаю многие долго ждали этой новости, и наконец-то дождались.

Разработчики предствили пока что первые 4 части книги "symfony Forms in Action":

Эти главы покрывают все, что нужно для того чтоб начать работать с формами в новой версии symfony 1.1. Если вы разрабочик тогда желательно прочитать все части с 1 по 4. А если вы дизайнер тогда достаточно прочитать 3 часть, где расказуется как работать с макетами для форм.

Первые части расказывают о всех возможностях, которые так же были доступны в версии symfony 1.0, а вот остальные части книги раскажут о дополнительных возможностях, которые будут доступны только в 1.1. Полное содержание книги:

  • Создание форм
  • Проверка форм (Валидация)
  • Формы для веб дизайнеров
  • Интерграция с Propel
  • Дополнительные формы
  • Структурированные формы
  • Дополнительные формы для веб-дизайнеров
  • Интернационализация и Локализация
  • Расширение ваших форм
  • Использование с другими фреймворками (frameworks)
  • Приложение A - Связи с Виджетами (Widgets)
  • Приложение B - Связи с Валидаторами (Validators)

От разработчиков: Надеемся, эта книга поможет вам в изучении форм. И пожалуйста, не поленитесь оставить отзыв или идеи о том как можно улучшить эту книгу. Если найдете ошибки то сообщите об этом в trac system.

Источник: http://www.symfony-project.org/blog

От меня: В ближайшее время ждите переводов глав книги на русский язык на моем блоге.

Filed under Symfony having 3 Comments »

Archives Posts

Многоязычные формы

June 16th, 2008 by pilot

В новой версии symfony 1.1 значительно упростили работы с многоязычными формами (интернационализация - i18n). В этом посте вы научитесь как создавать такие формы.

Итак возьмем простую многоязыную пропел схему:

propel:
  article:
    id:         ~
    author:     varchar(255)
    created_at: ~
  article_i18n:
    title:      { varchar(255), required: true }
    content:    longvarchar

После того как база сконфигурирована, выболняем команду propel:build-all для генерация пропел модели и классов для работы с формами:

$ php symfony propel:build-all

Вот такой спиской файлов автоматически создасться в папке проекта:

lib/
  form/
    ArticleForm.class.php
    ArticleI18nForm.class.php
    BaseFormPropel.class.php
  model/
    Article.php
    ArticlePeer.php
    ArticleI18n.php
    ArticleI18nPeer.php

Мы хотим одновременно обновлять обе версии нашей статьи Английскую и Французкую в одной форме:

i18n-form

Если вы пробовали сделать подобное в symfony 1.0, вы уже знаете, что это долгая и местами утомительная задача.

Благодаря улучшенияв в symfony 1.1, это задача выполняется в течении 2х минут.

Первое, добавим языки которые хотим использоваться в ArticleForm class:

class ArticleForm extends BaseArticleForm
{
  public function configure()
  {
    $this->embedI18n(array('en', 'fr'));

    $this->widgetSchema->setLabel('en', 'English');
    $this->widgetSchema->setLabel('fr', 'French');
  }
}

И второе, генерируем CRUD модуль для того чтоб наш web интерфейс мог показывать список статей (list), создавать их (create), обновлять (update), и удалять (delete):

$ php symfony generate:crud frontend article Article

Наслаждаемся полность рабочим модулем /frontend_dev.php/article.

Filed under Symfony having 3 Comments »

Archives Posts

Работа с формами в Symfony 1.1

June 14th, 2008 by pilot

Помимо всех внешних и внутренних изменений в новой версии symfony 1.1, больше всего изменений каснулось работы с формами и хелперами.

Так хелперы в новой версии действительно стали больше похожими на хелперы, теперь они представленны ввиде классов. Но пока, что самое интересное - это работа с формами, вот ссылка на статью (на английском) - 7 Дней с Symfony 1.1 - формы, виджеты и валидаторы.

Для прехода между днями, в конце ссылки меняйте цифру - day1, day2 …, day7

Filed under Symfony having No Comments »

Archives Posts

Как создать отимизированую версию сайта под iPhone в Symfony 1.1

June 11th, 2008 by pilot


Symfony 1.1 предлагает поддержку различных форматов и mime-types. Это означает что одна и таже связка модель и контроллер могут иметь различные шаблоны опираясь на формат запроса. Формат по умолчанию это HTML, но symfony поддерживает ряд дургих форматов представления, все они определены в factories.yml:

request:
  class: sfWebRequest
    param:
      formats:
        txt:  text/plain
        js:   [application/javascript, application/x-javascript, text/javascript]
        css:  text/css
        json: [application/json, application/x-json]
        xml:  [text/xml, application/xml, application/x-xml]
        rdf:  application/rdf+xml
        atom: application/atom+xml

Каждый фомарт соспостовялется с одим или несколькими mime-types. Эти mime-types используются для автоматического определения формата запроса, путем парсинга принятого HTTP заголовка (Accept HTTP header). Это очень удобно, если вы хотите сделать доступными ваши данные через браузер. Для изменения формата ответа (response format), клиенту Вашего веб сайта нужно только сменить принимаемый заголовок (Accept header) как показно ниже:

$ curl -H “Accept: application/xml” http://ws.example.com/api/article # to get a XML representation of the data
$ curl -H “Accept: application/json” http://ws.example.com/api/article # to get a JSON representation of the data

Поддерживать разные форматы данных так же легко как создавать разные шаблонов. Допустим наше приложение расположено в api/article. Ниже показан список шаблонов, который нужно создать в apps/frontend/modules/api/templates для поддержки форматов HTML, XML, и JSON:

articleSuccess.php
articleSuccess.xml.php
articleSuccess.json.php

По умолчанию, symfony изменит Content-Type в выводе согласно формату, и все не-HTML форматы, в макетах будут отключены. Даже partials (части) и макеты могут быть разные относительно формата запроса. К примеру, если вы подключите несколько партиалов в шаблоне, то подключаемый имя подключаемого партиала будет зависеть от текущего формата:

_list.php
_list.xml.php
_list.json.php

Разберем другой пример. Вы хотите “на лету” создать какой либо файл стилей (stylesheets) или JavaScript. Так как мы не можем всегда рассчитывать на Accept HTTP заголовок браузера для этих целей, мы можем переназначить формат с помощью специальной переменной sf_format в наших правилах роутинга (routing ruls). Ниже как создать роутинг для динамическогих стилей (stylesheet):

css1:
  url:   /css/dynamic1.css
    param: { module: css, action: dynamic, sf_format: css }

Так же можно использовать переменную sf_format в шаблоне URL разрешая несколько форматов для одного действия (action):

api_article:
  url:   /api/article:.sf_format
    param: { module: api, action: article }
    requirements:
      sf_format: (?:html|xml|json)

Большую часть времени нам не нужно менять одиночные строки в действии (action) для поддержки нового формата, но если нам действительно нужно выполнить что-то особенное для формата, можно вызвать $request->getRequestFormat(), получить текущий формат и действовать соответствующе.

Так, а теперь создадим оптимизированную версию нашего сайта под iPhone. Форамата для iphone нет в сборке по умолчанию, но добавить его очень просто. Первое, нам нужно определить что запрос пришел с iPhone. Если заголовок User-Agent содержит слова Mobile и Safari, мы можем быть уверенными что этот браузер в iPhone. Добавляем эту логику в ProjectConfiguration класс и определяем прослушивать события request.filter_parameters:

// config/ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    // ...

    $this->dispatcher->connect('request.filter_parameters', array($this, 'filterRequestParameters'));
  }

  public function filterRequestParameters(sfEvent $event, $parameters)
  {
    $request = $event->getSubject();

    if (preg_match('#Mobile/.+Safari#i', $request->getHttpHeader('User-Agent')))
    {
      $request->setRequestFormat('iphone');
    }

    return $parameters;
  }
}

Теперь каждый раз при запросе вызывается метод filterParameters() и если браузер в iPhone, формат запроса (request format) изменяется под iphone.

Вот и все! Теперь, любой запрос с iPhone будет использовать шаблон *Success.iphone.php вместо шаблона *Success.php.

Если вы используете особые стили (stylesheets) или JavaScript для поддержки iPhone (к примеру если вы используете iui библиотеку), вы так жу можете сконфигурировать view для прослушивания view.configure_format:

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    // ...

    $this->dispatcher->connect('view.configure_format', array($this, 'configureIPhoneFormat'));
  }

  public function configureIPhoneFormat(sfEvent $event)
  {
    if ('iphone' == $event['format'])
    {
      // add some CSS, stylesheet, or whatever you want
    }
  }
}

Вчера, Apple представила новый iPhone 3G. В честь такого события Фабьен (разработчик symfony) , представил документацию symfony API с поддержкой iPhone, скриншот в начале поста.

Благодаря новой поддержке форматов в Symfony 1.1, представлять совой сайт в разных форматах нет ничего проще, достаточно добавить шаблон для нового формата.

Оригинал статьи.

Filed under Symfony having 12 Comments »

Archives Posts

Вышел Symfony 1.1 RC2

June 10th, 2008 by pilot

Итак второй релиз кандидат отличноного фреймворка.


Подбробности изменений можно прочитать на офф сайте.


Для обновления существующего проекта основанного на версии 1.1 выполните:


$ php symfony propel:build-model
$ php symfony propel:build-forms
$ php symfony cache:clear



Для обновления проекта использующего symfony 1.0 внимательно прочитайте инструкцию обновлению.


Следующим шагом будет релиз Symfony 1.1 stable

Filed under Symfony having No Comments »

Archives Posts

Как самому настроит структуру папок в Symfony 1.1

June 10th, 2008 by pilot

В новой версии Symfony 1.1 появилась возможность настроить структуру папок на свое усмотрение.


Все проекты имеют идентичный стандарт кодирования, и соответственно одинаковую структуру папок (директорий).  Такая организация позволяет нескольким разработчиками работать над одим проектом одновременно. Так же это увеличавает ремонтопригодность проекта, в случае если вас попросили что-то исправить в проекте построенном на symfony, вы уже знаете где какие файлы находятся и можете практически сразу приступить к доработкам.


Но иногда (а на наших хостингах - довольно часто), нам нужно измененить структуру папок которую предлагает symfony.


Рассмотрим два варианта реализации :


Первое, допустим что ваш проект symfony на хостере должен находиться в папке public_html (здесь я имею ввиду что web папка symfony должна ссылаться на public_html хостера). Для этого редактируем ProjectConfiguration class, меняем поумолчанию указанную директорию web на нужнную нам public_html как показано ниже:


// config/ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup(){
$this->setWebDir($this->getRootDir().’/../public_html’);
}
}



И второй пример. К примеру ваш проект на symfony хостится в компании с повышенными требования к безопастности. Они не дают возможность вашему приложению записывать в любую папку проекта (к примеру cache и log), а только в определенную папку в которую разрешена записть (к примеру /tmp). Так как symfony пишет только в две папки (cache и log), очень просто снова обновить ProjectConfiguration class переместив эти папка в /tmp:


// config/ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup(){
$this->setCacheDir(’/tmp/myproject/cache’);
$this->setLogDir(’/tmp/myproject/log’);
}
}



Метод setCacheDir() позволяет менять не только константу sf_cache_dir, но также все что связаны с кешем: sf_app_base_cache_dir, sf_app_cache_dir, sf_template_cache_dir, sf_i18n_cache_dir, sf_config_cache_dir, sf_test_cache_dir, и sf_module_cache_dir.


Так же отмечу что, все классы конфигурации (configuration classes) так же действуют в symfony CLI, все изменения так же действуют на группы задач symfony и задачи которые вы назначили сами.


Благодаря новым классам конфигурации (configuration classes) symfony 1.1, настроить framework под свои требования очень просто.

Filed under Symfony having No Comments »

Archives Posts

Обновление документации Framework Symfony

June 7th, 2008 by pilot

Команда разработчиков Framework Symfony, провела ряд обновлений в документации:

  • The Definitive Guide to symfony” документация обновлена в данный момент в версию 1.1 включены практически все отличия от версии 1.0. Разработчики обещают, что полная документация новой версии фреймворка 1.1. выйдет раньше чем чем официальный релиз самого фреймворка.

  • По мере разработки новой документации 1.1, в блоге будут сообщать о новых руководствах по разрботке для версии 1.1 (они входят в symfony Cookbook),  сейчас можно прочитать о первом таком руководстве “Как использовать Propel 1.3 в Symfony 1.1“.

  • Так же возобновили перевод старовое руководство по Symfony - Askeet на разные языки, так как это наиболее актуально в данный момент. К сожелению русской версии перевод еще нет.

  • Из всего самое полезное - это добавлен поиск в Symfony API, что теперь позволяет легко находить нужные классы и методы по имени:



  • Так как Symfony поддерживает и Propel и Doctrine для объектной работы с базой данных (ORM) и многие пользователи используют Doctrine, разработчики разделили версии The symfony 1.0 “My First Project” на Propel и Doctrine



Полный список именений можно прочитать на http://www.symfony-project.org/blog/.

Filed under Symfony having 6 Comments »

Archives Posts

FirePHP — расширение FireBug для вывода отладочной информации PHP в консоль FireBug.

June 7th, 2008 by pilot




FirePHP — расширение FireBug для вывода отладочной информации PHP в консоль FireBug.


На сайте имеются библиотеки для подключения к Symfony, Zend Framework, CodeIgniter.


Взято с http://rmcreative.ru

Filed under Symfony having 1 Comment »

Archives Posts

Ускоряем разработку на Symfony в Eclipse

June 5th, 2008 by pilot

Так как Eclipse позволяет нам сохранять как шаблон часто используемые фрагменты кода, а потом вызывать их через (Ctrl+Space), то грех этим не воспользоваться.


Даже если Symfony успешно применяет концепцию “Не повторяй себя” (Don’t Repeat Yourself - DRY), часто, во время разработки, мы пишем одинаковые фрагменты кода.


К примеру, выбрать все записи пропеловского объекта (propel object):


$c = new Criteria();
$objects = PropelObjectPeer::doSelect($c);



В этом посте я хочу показать как создавать шаблоны фрагментов Symfony кода в Eclipse PDT.


КАК СОЗДАВАТЬ ШАБЛОНЫ:


- Кликаем Window, Preferences..
- Выбираем PHP из списка опций
- Выбираем Templates..


- Кликаем New.. и вставляем:
- Name (имя по которому будет вызываться шаблон при редактировании кода)
к примеру “doselect”
- Context: PHP
- Небольшое описание шаблона:
к примеру: “Criteria + doSelect costruct”
- И сам шаблон (pattern):


$$c = new Criteria;
$$${objects} = ${propelObject}Peer::doSelect($$c);



- Теперь, при редактировании php файла, напишите: “doselect” и нажмите (Ctrl+Space).


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


- Изменив $имя переменной, жмем TAB.
Курсор переместиться к имени пропел объекта (propel Object name) и позволить изменить его значение.


- Изменив propel Object name…  мы получили наш фрагмет кода, все эти действия займут несколько секунд.


МОИ SYMFONY ШАБЛОНЫ ДЛЯ ECLIPSE


Я написал группу symfony шаблонов под eclipse.

Вы можете скачать symfony-templates.zip и импортировать:

- распакуйте xml файл из zip архива
- Кликаем Window, Preferences..
- Выбираем PHP из списка опций
- Выбираем Templates и Кликаем Import…
- Выбираем symfony-templates.xml и подтверждаем.


Теперь вам доступны сокращения:


- action
public function execute${Action} {
${body}
}



- controller
class ${ControllerName}Actions extends sfActions {public function execute${action}()
{
${body}
}
}




- doselect
$$c = new Criteria;
$$${objects} = ${propelObject}Peer::doSelect($$c);



Оригинал статьи здесь

Filed under Symfony having No Comments »

« Previous Entries Next Entries »