Mar 26

Засел я сейчас за написание давно обещанной статьи про новый Form Framework, который будет включен в состав Symfony 1.1. Пока разобрался, что и как подключать - Symfony 1.1 Sandbox упорно не хотел работать с базой данных так, как нужно было бы, пока поглядел в кодах - что и как нужно делать (а то порядком уже подзабыл всё, что я смотрел при прошлом просмотре Symfony 1.1). В общем, решил я, что одной статьей дело не обойдется - слишком уж много всего рассказывать нужно, так что с завтрашнего дня я буду выкладывать одну статью в день, которые будут касаться форм в Symfony 1.1. Эти статьи можно будет считать “русским аналогом” вот этого цикла статей - это не будет перевод статей, скорее я буду руководствоваться тем, что написано там, чтобы знать, куда дальше двигаться в своем повествовании, при этом, возможно, останавливаясь на некоторых моментах, которые, на мой взгляд, достаточно важны для новичков в Symfony.

В общем, посмотрим… Завтра посмотрим. :)

PS. Сегодня, кстати, вышла вторая бета-версия Symfony 1.1, на которой я и буду тестировать всё, что я напишу. Список изменений по сравнению с Symfony 1.0 лежит здесь - достаточно занимательное чтиво.

written by FX Poster \\ tags: ,

Mar 04

Со следующей версии Ubuntu (а это, как мы все помним, будет 8.04 или Hardy Heron) в неё будет включен Zend Framework. Правда не уточняется, что на самом деле значат слова “to be an integral part of the Ubuntu distribution” - либо ZF просто будет включен в поставку по умолчанию (что, на мой взгляд, не бог весть какое достоинство), либо у убунтовцев и Canonical действительно на ZF есть планы (создание средств разработки с использованием ZF, типа Zend Studio, либо построение системы управления Ubuntu’ой на PHP и ZF, во что, лично я не сильно верю)… В общем - я достаточно смутно представляю, какие преимущества от этого “сотрудничества” получат пользователи Ubuntu, но… Поживем - увидим.

PS. Mac’и поставляются с RoR, а Ubuntu - с ZF. :)

written by FX Poster \\ tags: ,

Feb 26

Хочется немного прокомментировать предыдущую статью и отзывы как о ней (основная их часть, конечно, на Хабрахабре), так и о фреймворке в целом.

  1. Я вообще считаю, что пишу не слишком интересно (по сравнению с людьми, блоги которых я читаю), но реакция на некоторые мои посты говорит совершенно иное, и я этому очень рад.
  2. Статья, ИМХО, удалась. И, судя по отзывам, многие вполне не прочь прочитать что-нибудь еще по этой теме. Хотя, если честно, я рассчитывал на иной результат - многим (особенно в рунете) кажется, что Symfony слишком тормознутая и сложная, и что тратить время на её изучение совершенно не стоит, ведь есть всякие CodeIgniter‘ы и прочее. Оказалось, всё не совсем так, и еще есть люди, которые думают иначе (а есть и такие, которые стали думать иначе после моей статьи)… И я этому очень рад.
  3. В рунете очень мало ресурсов по Symfony… И мне хочется немного заполнить эту нишу. Да, уже есть перевод книги по Symfony (хоть и не полный) на русский язык, но этого мало. В рунете не хватает простых “туториалов” - как делать то или иное, с какой стороны подходить к этому фреймворку, пошаговых примеров разработки приложений (типа 24-хдневного guide’а по построению Askeet)… С одной стороны - я не сильно люблю писать тексты для чайников (либо переводить зарубежные), но с другой - мне, в принципе, не сложно, а если другим будет от этого польза - то я буду только рад. Стоит ли мне писать что-то подобное?

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

PS. Писать часто буду вряд ли - времени нет особо… Но я стараюсь выделять своему блогу время. :) 

PPS. Пост про Symfony 1.1 Form Framework будет… Очень надеюсь, что на этой неделе…

PPPS. Писать на Хабрахабр интересные статьи очень выгодно:

Yandex Counter

written by FX Poster \\ tags: ,

Feb 26

Чем больше я работаю над своим первым проектом на работе, тем больше мне хочется в нем поменять и тем больше я жалею о том, что перед началом работы я не прочитал до конца «The Definitive Guide to Symfony» и не изучил плагины для Symfony. Многие из них мне бы помогли намного сократить время разработки и, что самое главное, не думать о том, как красиво реализовать те или иные вещи… И еще одно — если у вас уже есть кусок системы (как это было у меня), который вы собираетесь переписывать с использованием вашего фреймворка (или просто переписывать, потому что код вам не нравиться) — то мой вам совет — потратьте время на то, чтобы спроектировать этот кусок на план вашей новой системы, не бросайтесь сразу всё переписывать (каюсь, я поступил именно так), так как после анализа (который, возможно, займет у вас не один день, и даже не одну неделю), возможно, от предыдущей архитектуры системы не останется и следа.

Вообще, я люблю проектировать, продумывать, анализировать те или иные решения, которые хочу внедрить в систему (хотя, признаюсь, опыта у меня в этом маловато), но как обьяснить заказчику, что ты провел день в раздумьях… Эх…

Ну ладно, это я отвлекся. Сегодня хочется рассказать о том, с чего стоит начать при разработке системы с помощью Symfony и каких правил следует придерживаться.

Continue reading »

written by FX Poster \\ tags: , , , ,

Feb 14

Мдя, заработался совсем… Писать нет времени абсолютно… Поэтому сегодня будут ссылки:

И напоследок: мне недавно нужен был перевод из русского UTF-8 на латиницу в PHP. Ддо этого я его делал так: считываем по символу (или по нескольку символов) из строки и строим новую строку транслитерированием. Из плюсов - быстро, из минусов - напрягает выбирать по нескольку букв. Потом мне предложили использовать str_replace. Из плюсов - быстро пишется. К сожалению, долго работает. :) Есть и еще один вариант:

function rus_to_translit($string)
{
  $converter = array(
    'а' => 'a',  'б' => 'b',  'в' => 'v',   'г' => 'g',  'д' => 'd', 'е' => 'e', 'ё' => 'e', 'ж' => 'zh',
    'з' => 'z',  'и' => 'i',  'й' => 'y',   'к' => 'k',  'л' => 'l', 'м' => 'm', 'н' => 'n', 'о' => 'o',
    'п' => 'p',  'р' => 'r',  'с' => 's',   'т' => 't',  'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c',
    'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sch', 'ь' => '\'', 'ы' => 'y', 'ъ' => '',  'э' => 'e', 'ю' => 'yu',
    'я' => 'ya',
    'А' => 'A',  'Б' => 'B',  'В' => 'V',   'Г' => 'G',  'Д' => 'D', 'Е' => 'E', 'Ё' => 'E', 'Ж' => 'ZH',
    'З' => 'Z',  'И' => 'I',  'Й' => 'Y',   'К' => 'K',  'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O',
    'П' => 'P',  'Р' => 'R',  'С' => 'S',   'Т' => 'T',  'У' => 'U', 'Ф' => 'F', 'Х' => 'H', 'Ц' => 'C',
    'Ч' => 'CH', 'Ш' => 'SH', 'Щ' => 'SCH', 'Ь' => '\'', 'Ы' => 'Y', 'Ъ' => '',  'Э' => 'E', 'Ю' => 'YU',
    'Я' => 'YA',
  );

  return strtr($string, $converter);
}

При этом не забудьте файл, в который вы это пишете сохранить в кодировке UTF-8. ИМХО, оптимальный вариант.

PS. Не забудьте сегодня поздравить свои половинки с днем всех влюбленных!

written by FX Poster \\ tags: ,

Feb 09

Блин, “всё гениальное - просто”. И решение моей проблемы оказалось до ужаса простым, причем думать даже не пришлось - просто как-то случайно подумалось…

Для начала небольшое уточнение - все места, где мне нужно получать все записи (а не только “одобренные”) находятся в одном или нескольких модулях (компонентах, если кому так больше нравиться) системы (например, пользовательское изменение данных в уже добавленной, но еще неодобренной записи и админка).

Для тех, кто не читал предыдущий пост - советую всё же прочитать.

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

class Product {
  public static $showUnapproved = false;

  private static function fetchByParameters($sql)
  {
    if(!self::$showUnapproved) {
      // добавляем "WHERE approved = '1'" в наш sql-запрос
    }
    ...
  }

   ...
}

Теперь у нас по умолчанию будут везде показываться только approved-записи, а для нужных модулей в каком-нибудь preExecute для контроллера нужно добавить Product::$showUnapproved = true.

Поддерживать такой код гораздо удобнее, чем во всех остальных случаях.

written by FX Poster \\ tags:

Feb 06

В процессе написания сайта с использованием Symfony начали проявляться недостатки этой замечательной, на мой взгляд, библиотеки…

Первое, о чем хочется сказать - очень удобно реализованы связи one-to-many. Propel сама сгенерирует базовые классы, в которых такие связи будут учитываться изначально. Пользоваться очень удобно, своего кода в моделях приходится писать очень мало, а если быть более точным - почти весь код в данном случае получается именно product-specific. В случае со связями one-to-one проблемы появляются - как я этого ни добивался, Propel упрямо считает эти связи такими же, как и one-to-many и генерирует неправильный код. Исправляется обычно дописыванием правильных функций вручную, благо, обычно дописать только get<PrimaryKey>-функции. В моем случае я вообще перестроил БД так, что таких связей у меня не оказалось, так что конкретного ничего сказать не могу.

Второе - “всё - обьекты”. Очень популярное в ООП высказывание подходит к Propel’у просто замечательно. :) Работа с Propel’ом заключается исключительно в работе с обьектами-записями и обьектами-таблицами. Никаких php’шных массивов (привет CI и CakePHP), одни классы и обьекты. Очень удобно. С эффективностью, правда, могут возникать огромные проблемы. Я, кстати, так до сих пор и не знаю, как эффективно выбрать (категория + количество продуктов в ней) за один запрос. Но беспокоиться об этом я буду уже потом. :)

Блин, вот сидишь на работе и думаешь - сколько всего можно написать, плохого и хорошего, а приходишь домой и нифига не вспоминается.

Третье - many-to-many. После того, как у меня появились такие связи, я начал очень сильно жалеть о том, что я не выбрал Doctrine… По сравнению с ней (она дополнительную many-to-many таблицу создает сама и сама же за ней следит) в Propel’е всё ужасно - приходится создавать вручную таблицы и дописывать в них целую кучу кода, который бы вполне могла дописать сама библиотека в базовых классах. Может в том же CI это вполне нормальным кажется (контраст другой), но здесь, когда строишь модель базы данных - мыслишь исключительно в обьектах, которые тебе будут нужны. И добавлять (а еще сопровождать) эту [непонятно откуда взявшуюся, в реале-то её нет] таблицу очень неудобно.

Четвертое - опять по сравнению с Doctrine’ой - нет возможности “опускаться” на уровень SQL не теряя ORM’а. Т.е. либо Propel ORM, либо Creole (PDO). В Doctrine’е есть для таких случаев DQL - достаточно удобная штучка, если поглядеть по мануалу. Вообще, Doctrine, на мой взгляд, гораздо более функциональная, мощная и удобная библиотека. Да и User Guide’ы у неё гораздо более полные и, как ни странно, user-friendly.

Но по сравнению со всем остальным, что я видел на PHP - Propel - это очень круто.

written by FX Poster \\ tags: , ,

Feb 02

Столкнулся я вот тут с ситуацией и хочу попросить помощи у читателей.

Имеется:

Таблица в базе данных, содержащая некоторые записи. У записей есть “переключатель” - одобрена/неодобрена (для тех, кто в танке - булевое поле approved). Для этой таблицы (и всех остальных таблиц в бд) есть ORM.

Нужно:

Обеспечить для большей части частей системы удобный доступ только к записям с approved = true, при этом нужно учесть, что другие таблицы также могут быть связаны с данной и в ORM’е есть метода доступа к записям в данной таблице. Грубо говоря имеем нечто типа такого:

Table ProductType
Table Product
$someProductType->fetchAllProducts()
Product::fetchAll()

То есть, доступ к данной таблице есть во многих местах и все такие места менять ОЧЕНЬ не хотелось бы.

Но это половина проблемы, и в моем случае не самая страшная т.к. у таблицы есть ОДИН метод, к которому обращаются все остальные (пусть это будет Product::fetchByParameters()), и заменив только его я получу то, что мне нужно.

Главная проблема в том, что мне еще нужно в некоторых местах доступаться ко всем записям, даже неодобренным. Таким образом, способ приведенный выше отпадает. Каким образом можно подобную функциональность поиметь - я не представляю. Кто-нибудь может помочь?

written by FX Poster \\ tags:

Jan 22

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

Работа с формами здесь реализована на основе хелперов и валидаторов, которые напрямую друг с другом не связаны вообще никак. Поподробнее можно почитать в онлайн книге, в главе про формы.

Пример работы:

Предположим, что существует следующая модель пользователя (здесь и далее все конфигурационные файлы будут пприводится в формате YAML) :

user:
 id:
 login:
   type: varchar(64)
   required: true
   index: unique
 password:
   type: varchar(40)
   required: true
 first_name:
   type: varchar(64)
   required: true
 last_name:
   type: varchar(64)
   required: true
 email:
   type: varchar(128)
   required: true
   index: unique

...

Continue reading »

written by FX Poster \\ tags: , , ,

Jan 20

Не так давно я задавал вопрос относительно выбора PHP-фреймворка из множества ныне существующих… Отзывы послушал… Кое-что почитал по самим фреймворкам… В итоге для себя я выбрал Symfony (пусть тормозная, но вы часто делаете сайты с количеством посетителей от 10 000 в день?). Почему - вопрос сложный и, наверное, я сам до конца не знаю ответа на него… Хотя одну из основных причин могу сказать - это модель, а именно Propel/Doctrine. Это единственные на данный момент ORM’ы с которыми мне реально нравится работать, разработчики которых понимают отличия функциональности уровня таблицы и уровня записи и т.д. (может есть еще хорошие ORM’ы, но я с ними просто незнаком :)) Да, кстати, я сейчас использую Symfony по работе, за что огромное спасибо Любомиру, моему “шефу”. :)

Но сейчас я хотел бы поговорить не об этом… Есть одна “маленькая”  идея - затеять сравнение фреймворков друг с другом. По каким критериям сравнивать - вопрос довольно сложный, я составил следующий список:

  • Controller
  • Model
  • View
  • наличие/удобство хелперов
  • взаимодействие с JS/AJAX
  • работа с формами (сейчас с этим в Symfony, кстати, достаточно большие проблемы)

Пунктов, я думаю, с вашей помощью добавится еще с десяток. Так что жду предложений.

Следующий вопрос - список фреймворков. Опять же, мой список пока что состоит из таких претендентов:

Писать хочу в виде “один пост рассматривает все фреймворки по одному критерию”. Т.е., например, через две недели будет опубликовано сравнение моделей в выбранных фреймворках - возможности, удобства, недостатки, пожелания относительно улучшения и т.д.

Теперь я подошел к самому главному - хотелось бы попробовать устроить действительно коллективную работу… Никто не хочет помочь мне в этом деле? Я вот лично могу на себя взять Symfony и (хотя и не хочется) Kohana. Никто не хочет написать про CakePHP или про <вставьте сюда название вашего любимого фреймворка>? На каждый пост будет отводится, скажем, неделя-две. После этого кто-то (думаю я, если кто-то захочет помочь - пишите) скомпонует все посты в одно сравнение, сделает выводы…

Первым критерием для сравнения предлагаю сделать Controller и всё что с ним связано (routes, dispatchers  и т.д.). Если меня кто-то поддержит - жду ваши тексты до 1-го февраля. И 3-го будет первый пост по сравнению фреймворков.

written by FX Poster \\ tags: ,