Zend_View и encoding

Смотрю я теперь на исходный код Zend_Controller_Front , Zend_Controller_Action, Zend_View, а также на Zend_View_Abstract у Zend Framework версии 1.7.3, чтоб понять, как в них обстоят дела с encoding.

Продолжая тему MySQL + PHP: charset и collation и правильные мысли и изучение векторов, которые подкинул Алексей Захлестин, я наткнулся на замечательный private член класса Zend_View_Abstract под названием $_encoding, со значением ISO-8859-1. Так-же в этом классе я нашёл как в Zend_View_Abstract устроен метод escape. Этот $_encoding на него влияет, так как в методе escape он является третьим параметром к функциям htmlspecialchars или htmlentities (какую из них использовать вы тоже можете настроить).

Вот смотрю я на их исходный код и понять не могу, как нормальным и безболезненным способом в объект Zend_View передать мне нужный encoding? Везде в уроках по Zend Framework можно увидеть, как во всех View используют строку <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ /> или соответствующую строку из helpers API у Zend_View, но я нигде не замечал как сменить внутреннюю настройку. Ну, кроме наисложнейших манипуляций со всей иерархией bootsrap, ведь есть замечательный helper Zend_View_Helper_Doctype.

Ведь, если бы была единая настройка encoding для всех компонентов Zend Framework, как бы было удобно и не возникала таких проблем, как были у нас. Разработчикам не нужно было-бы думать о том, в каком encoding у них клиент для работы с базой данных, в каком encoding у них страницы, в каком encoding у них остальные используемые компоненты Zend Framework — обо всём позаботились бы в одном месте и сразу.

Может я чего упустил — ткните в соответствующий урок или страницу мануала.

MySQL + PHP: charset и collation

Работаю я над одним проектом, где в день проноситься до миллиона уникальных посетителей в день. Для этого проекта я с командой работаю над маленьким сателлитом, назначения которого не имеет столь весомого значения, сколько имеет значение проблема, с которой я сегодня столкнулся. И нам крупно повезло, что кол-во данных сейчас на сателлите мизерное и он пока находиться в стадии тестирования и нагрузка на нём растёт постепенно.

Проект пишется на PHP 5.2.x + MySQL 5.0 Так как проект международный, база сателлита находиться в collation utf8_unicode_ci.

У сателлита есть 2 части: так называемая клиентская и административная. Клиентская доступна всем и дёргается постоянно, административная только администраторам, ею пользуются раз в неделю примерно пока.

Клиентская часть, из-за ожидаемой нагрузки, писалась полностью мною, без использования каких-либо фреймворков, каркасов и прочего. Благо её простейшие функции позволяли это сделать быстро. Естественно, в качестве MySQL клиента был выбран mysqli, всё как надо, сразу после соединения был выставлен нужный charset, строго как в мануале:

$conn->set_charset("utf8")

Сам mysqli был выбран потому-что проект новый и у него вроде-как получше с поддержкой UTF-8 всё устроено.

Административная часть писалась коллегой, на пару со мной, причём ответственность за качество кода лежит на мне. Для большей скорости написания мы использовали Zend Framework, который мы оба довольно не плохо освоили к этому моменту. К тому-же, административная часть имела куда больше функций и меньше нагрузки, нежели клиентская. Единственное разногласие, которое у нас было с коллегой, это использовать или нет Zend_Form или нет из-за очень сложной кастомизации самих форм и их декораторов, неразумного использования комбинации <dd> и &ltdt> вокруг скрытых полей и прочих мелких религиозных и языковых разногласий. Ни одному из нас не возник простейший вопрос, как устроен другой компонент — Zend_Db. Определит ли он сам charset и collation, который мы используем и нам нужен или будет использовать тот, что установлен по умолчанию. И вот, сегодня мы поняли что мы выстрелили себе в ногу примерно две недели назад — не то пуля летело медленно и наконец долетела, не то порох сырой ныл и сработал только сейчас.

Я всегда думал, что умный Zend_Db как-то сам узнает какой нужно charset и collation использовать, раз он сам узнаёт какие поля у таблицы и какие значения туда можно писать, а какие нет. Оказалось что нет… Я был не прав и ему об этом нужно грубо говорить (ну или клиенту вдолбить в настройки по умолчанию).

Поэтому в самом начале ему пришлось прописать следующие строку сразу после инициализации:

$db->query('SET CHARACTER SET utf8');

Теоретически, если следовать документации Configuring the Character Set and Collation for Applications, хватило-бы только SET NAMES ‘utf8’, но в таком случае collation остался бы utf8_general_ci — а нам этого не хочется. Поэтому, копнув немного глубже, в Connection Character Sets and Collations, было найдено SET CHARACTER SET utf8.

После данных изменений со стороны административной части на Zend Framework, замены $conn->set_charset(“utf8”); тоже на $conn->query(‘SET CHARACTER SET utf8’); и правок в базе данных всё заработало прекраснейшим образом.

Я вот понять не могу, почему у Zend Framework нигде об этой проблеме не написано? Зачем у mysqli есть метод mysqli::set_charset, если он меняет collation на верный? Почему в PHP мануале написано не использовать «старый дедовский способ с SET NAMES»?

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

XML-RPC в Zend Framework 1.5 RC1

На днях разрабатывал для одного проекта тестовое API на основе XML-RPC. Конечно-же нужно было создать тестовую модель. Так как под рукой всегда есть PHP, я естественно взял Zend Framework 1.5 RC1 и посмотрел, что в нём есть по плану XML-RPC. Оказалось есть – Zend_XmlRpc, как клиент, так и сервер. Если посмотреть на примеры в документации – всё легко, просто и прозрачно. При первых попытках всё прошло очень и очень успешно. Как в написании клиента, так и в написании сервера. Что меня очень обрадовало и уже в ближайшие часы я сделал всю основную работу, всё работало идеально, пока я не захотел передать немного данных, закодированных по стандарту base64 (XML-RPC имеет специальный тип для этого).

Continue reading

Когда новости сами приходят

Сегодня получил письмо с приглашением присоединиться к сообществу Zend Framework, в котором общаются на моём родном русском языке. Отличная новость – русскоязычное сообщество, форум, раздел статей (правда на данный момент пустовато, но, как я понимаю, всё только начинается), полезные ссылки.

Очень приятно, что мой любимый Zend Framework начинает набирать обороты и становиться популярнее, следовательно, появятся примеры, статьи, уроки и жизнь разработчиков станет более лёгкой.

Ещё в сети можно найту Google Group: ru-zend-framework и конечно родной сайт Zend Framework.

Почему мне начинает нравится Zend Framework и PHP

  1. Мне нравиться PHP
  2. Мне очень нравиться PHP
  3. Мне нравиться то, как сделан Zend Development Environment и то, что Zend Development Environment прекрасно поддерживает Zend Framework с подсказками кода
  4. Мне нравиться то, что я всегда без проблем могу посмотреть в исходники Zend Framework и разобраться что к чему
  5. Мне нравиться Zend Framework потому что я могу продуктам с его использованием спокойно делать стандартный debug с Zend Development Environment, поставить Break point там где хочу и посмотреть как оно там всё происходит
  6. Мне нравиться, что я его могу тупо скачать как ZIP или TGZ, закинуть на сервер куда угодно, прописать в include_path и радостно пользоваться им как хочу
  7. Мне нравиться, про я могу использовать разные шаблоны запуска/создания проекта, именно такие, какие мне нравятся или кажутся нужными для проекта
  8. Мне нравиться, что PHP можно без проблем за несколько минут поставить почти на любую платформу, а значит там можно запустить Zend Framework

Zend Framework 1.0.0 – как бы я строил начальный каркас

Не знаю, на сколько я прав в этом вопросе, но я не думаю, что совершил много грубых ошибок в проектировании. Тех, кто далёк от архитектуры Model-View-Controller попрошу остановиться и ознакомиться где-либо с этой идеологией.

Итак, для установки Zend Framework 1.0.0 на сервер не нужно никаких особых шаманств с бубном. Всё что вам нужно, это соответствовать требованиям Zend Framework. Там нет ничего сложного – PHP 5.1.4 (рекомендуется 5.2.2), SPL и, возможно, некоторые extensions, если вы будете использовать определённые компоненты Zend Framework.

Структура каталогов для быстрого старта с Zend Framework о которой пойдёт речь далее.

Continue reading

Первые 8 часов с Zend Framework 1.0.0

Провёл с Zend Framework 1.0.0 около 8 часов. Результат: всё-таки я это дело запустил, подключился к базе, сделал 404 страницу, сделал форму регистрации. Подводных камней куча. Мануал по Zend Framework и примеры желают лучшего. По сравнения с Ruby on Rails стартовать реально сложно – примеры все написаны под разные версии до 1.0.0 и очень часто отличаются структурой.

Первое и самое лёгкое в процессе, это установка: всё просто – скопировал в папку, в include_path закинул и всё, можно пользоваться. Подробности – Introduction to Zend Framework, Installation.

Далее – контроллеры. С ними Quick Start прошёл тоже быстро. Фактически всё из Quick Start прошло без проблем, кроме 404 страницы. Всё сделал как они описали, но не заработало. Код я видимо взял из примера и у меня пробрался throwExceptions в режиме true, как только я понял что к чему, всё заработало. То, как устроена обработка 404ой ошибки с Zend_Controller_Plugin_ErrorHandler мне понравилось. Пока не разобрался с возможностью самому задавать правила роутинга, но это наверняка мелочь уже.

Что меня на данном этапе удивило – это то, что нет единой принятой структуры каталогов, как у Ruby on Rails. Конечно, в Quick Start есть пример, но всё это сделано руками и где-то в мануале, а на это статью не сразу натыкаешься. Я бы сказал не хватает Creating a weblog in 15 minutes – с Ruby on Rails я как-то проще начинал.

Итак, так как я уже разобрался с контроллерами и акшинами, я перешёл к конфигам. WOW! и никаких конфигов тоже небыло. Если надо – пожайлуста, делай сам, из массива, из .ini или из .xml. Где и как будет лежать – наши/ваши проблемы.

Конфиг есть, пора бы и за базой поработать. Обилие возможностей для работы казалось бы не может не радовать. Zend_Db_Select, Zend_Db_Table, Zend_Db_Table_Row. Осилил я Zend_Db_Table и Zend_Db_Table_Row. Часа 3 потратил на то, чтобы загрузить модели, ну или то, что в Zend Framework называется моделью. Оказывается, не смотря на то что в структуре примера есть папка application/models у меня их автоматом не грузит. Как их грузить я вообще не нашёл, поэтому тупо сделал им require_once и всё вроде заработало.
Пока не нашёл способа, куда вводить их моделям валидацию, как в Ruby on Rails, видимо, в Zend Framework всё реализовано по другому. Особо хакать исходники времени небыло, я оставил всё как есть. Потом меня приятно удивил метод save – в случае ошибки, он падает с Exception. Я ожидал что он элементарно будет возвращать true/false и всё. Ладно – обошли это проблему пока, и особых решений этой проблемы я пока не видел, зато видел где-то в их wiki много try { […] } catch { […] } при работе с их моделями.

Скажу честно – впечатления пока никакие. Я ожидал намного больше и со стороны документации и со стороны примеров. да и со стороны самого Zend Framework 1.0.0 я ожидал куда более простую систему, чем увидел. Может это и не верное первое впечатление, но именно оно отталкивает меня от использование Zend Framework в работе и заставляет меня использовать личные разработки.