![]() |
Начальный практикум в Yii
Официальный сайт фреймворка: http://yiiframework.com/
Русскоязычный форум: http://www.yiiframework.com/forum/index.php/board,19.0.html Версия фреймворка на момент написания статьи: 1.0.6 Автор: Кузьмин Антон (Kuzya) Сайт: http://kuzya.name К сожалению редактор форума не позволяет создавать структурированный текст, из-за чего большие части кода порой трудно читаются. В этом случае рекомендую Вам скачать PDF-вариант статьи: practical_intro_yii.pdf (17 страниц, шрифт Times New Roman, 12pt). Прикреплённые файлы: design.zip, ready.zip, database.zip Введение Здравствуйте. В этой статье мы будем практиковаться в изготовлении простейшего приложения с помощью фреймворка Yii. Нашей целью будет создание сайта на котором люди могут вести свои блоги и комментировать чужие. Скажу сразу что я являюсь ярым противником различных классов и хэлперов для работы с HTML. Поэтому, в отличие от демонстрационных приложений производителей, я не использую классы типа CHtml. Хотя возможно кто-то сочтёт это неправильным. Вообщем, все шаблоны в этой статье содержат только HTML и альтернативный PHP-синтаксис. Начните с создания "чистого" хоста для нашего сайта. Я назвал его "yii".В корневой директории создайте папку base. Скопируйте туда содержимое архива фреймворка (директории framework, requirements и т.д.). После этого, так же в корне, создайте новое приложение с помощью утилиты "yiic" и её команды webapp ( http://www.yiiframework.com/doc/guide/ru/quickstart.first-app ). Дизайн Возьмите архив с дизайном (приложен к статье). В нём есть директории fonts, images и файл style.css. Скопируйте их в корень сайта. Теперь пройдите в директорию /protected/views/layouts и откройте файл main.php. Здесь содержится глобальный внешний вид для всех без исключения страниц. Сначала просто скопируйте в этот шаблон HTML-содержимое нашего дизайна ( из архивного index.html ). После этого, при обращении к корню хоста, Вы должны увидеть совершенно другую картину. Главная переменная в layout`e это $content. Туда помещается содержимое текущей страницы. Давайте затрём приветствие Код HTML:
<h2>Здравствуйте уважаемый гость!</h2>PHP код:
( /protected/views/site/index.php ) и за место содержимого поместим ранее вырезанную часть layout`a. Обновите страницу. Внешне никаких изменений произойти недолжно. Локализация Локализацией ( http://www.yiiframework.com/doc/guide/ru/topics.i18n ) мы займёмся именно сейчас. Почему, Вы поймёте по ходу чтения этого раздела. Для начала настроим исходный язык приложения (sourceLanguage) и пользовательский (просто language). Для этого откройте файл конфигураций /protected/config/main.php и после параметров "basePath" и "name" добавьте соответствующие ячейки: PHP код:
языки будут совпадать то никакой перевод задействован не будет. Непосредственно преобразование английских фраз в русские мы будем осуществлять с помощью метода t, класса Yii, которому нужно передать категорию фразы, и саму фразу ( http://www.yiiframework.com/doc/api/YiiBase#t-detail ). Метод покопается в языковых файлах и вернёт текст перевода. Сами фразы мы будем хранить в виде массива, в php-файлах ( хотя возможны варианты, например хранение фраз в БД). Пройдите в директорию /protected/messages/ и создайте там папку ru_RU. В ней должны находиться файлы категорий с русскоязычными текстами. Мы будем пользоваться всего одной категорией ( естественно в настоящем приложении их несколько ) - common. Создайте для неё файл common.php со следующим содержимым: PHP код:
PHP код:
PHP код:
PHP код:
Такую работу мы будем проводить со всеми англоязычными фразами. Во избежание лишней траты времени я не стал локализировать надписи в формах, меню и т.д. Пусть сразу будут русскими. .htaccess Сейчас мы сделаем так чтоб URL у нас были не такие "index.php?r=path/path", а такие - "/path/path". Для этого откройте конфигурационный файл и в ячейку components добавьте PHP код:
Код:
Options +FollowSymLinksБаза данных Займёмся базой данных. Её SQL-код лежит в архиве database.zip. Создайте базу yii и выполните этот код в ней. Теперь следует указать фреймворку с какой базой ему нужно работать и как с ней соединяться. Снова обратимся к файлу /protected/config/main.php и раскомментируем в нём строки PHP код:
PHP код:
|
Регистрация
Самое первое что мы должны сделать на нашем сайте - соорудить регистрацию и авторизацию. Для этого мы модифицируем уже существующий у нас контроллер Site и создадим модель Users. Создание модели лучше всего производить с помощью утилиты yiic. Для этого запустите yiic с параметром shell и указанием индексного файла нашего приложения. После этого выполните команду "model Users". Создастся модель которую мы используем для работы с соответствующей таблицей. Сначала сделаем регистрацию. Объявите для этого метод actionRegister в контроллере Site. Впишем туда отображение формы регистрации. Она будет лежать в шаблоне /protected/views/site/register.php и иметь следующее содержимое. Код HTML:
<h2>Регистрация</h2>PHP код:
форма отсылает данные методом POST на этот же адрес. То есть при обращении к действию register контроллер должен как-то проверить - пришла форма, или это простое обращение. Такую проверку мы будем осуществлять проверяя существование массива $_POST['Users']. Если он есть - нам пришли данные из формы. В случае регистрации мы просто создадим новый объект модели Users, укажем необходимые поля и сохраним изменения. PHP код:
текст в языковой файл, в ячейку "registered" PHP код:
PHP код:
так чтоб она не отображалась если есть Flash-сообщение. В этом нам помогут методы hasFlash и getFlash этого же объекта. Первый определяет есть ли нужное нам сообщение, а второй это сообщение возвращает. Код HTML:
<h2>Регистрация</h2>PHP код:
Нам нужно проверить отсутсвие логина и указанного почтового адреса в базе. Для этого откроем файл /protected/models/User.php и посмотрим метод "rules". Там сейчас 3 правила - максимальная длинна логина 30 символов, пароля - 32, email`a - 50. Мы внесём сюда 5 правил - поля почтового адреса и логина не должны быть пустыми, содержимого этих полей в БД быть не должно, почтовый адрес должен иметь правильный формат. PHP код:
PHP код:
перед сохранением данных мы вызовем метод "validate". И в третьих, мы осуществим обработку метода getErrors, модели, так чтоб в $errors поместились все имеющиеся ошибки. Затем мы передадим массив с ошибками в обработчик шаблона. PHP код:
Код HTML:
<?if(count($errors)):?> |
Авторизация
Для авторизации мы будем использовать метод actionLogin, контроллера Site и шаблон /protected/views/site/login.php, содержимое которого мы поменяем на Код HTML:
<div id="bodyPanel">Этот метод содержит код благодаря которому пользователи могут входить на сайт. Работает он сейчас с двумя аккаунтами, информация о которых внесена непосредственно внутрь метода. Заменим его на код который будет брать информацию из базы данных. Сначала объявим два новых свойства: PHP код:
PHP код:
PHP код:
PHP код:
и номер мы получим с помощью "Yii::app()->user->getName()" и "Yii::app()->user->getId()" соответственно. Помните надпись "Здравствуйте гость!" на главной? Давайте сделаем так, чтобы она менялась в зависимости от того авторизирован пользователь или нет. Добавим в языковой файл соответствующую фразу. PHP код:
Код HTML:
<h2>параметра "login" (который содержится в фразе) логин пользователя. И немного модифицируем главное меню. Пусть авторизированный пользователь видит ссылки на главную, на выход и на создание новой записи. Для этого, в layout`e, заменим код Код HTML:
<ul>Код HTML:
<ul> |
Записи
Теперь займёмся основной частью нашего сайта - ведением записей. Всю нужную работу будет выполнять контроллер с именем Records. Создайте его с помощью утилиты yiic командой "crud Records" ( http://www.yiiframework.com/doc/guide/ru/quickstart.first-app и http://www.yiiframework.com/doc/guide/ru/topics.console ). Не забудьте предварительно создать и соответствующую модель, иначе контроллер просто не сможет быть создан и в командную строку выплеснется множество ошибок. Откроем файл /protected/controllers/RecordsController.php и обратим внимание на его методы. Первый из интересующих нас - "accessRules" (http://www.yiiframework.com/doc/guide/ru/topics.auth#access-control-filter). Здесь содержатся правила доступа к действиям контроллера. Сразу после создания они следующие: 1. Любым пользователям разрешено просматривать записи в виде списка и по отдельности (методы list и show) 2. Авторизированным пользователям разрешено добавлять записи и изменять их (методы create, update) 3. Администраторам разрешены функции администрирования и удаления (методы admin, delete) 4. Всё остальное всем запрещено В принципе, нам ничего тут менять не нужно. Только лишь передать права удаления авторизированным пользователям и стереть из прав действие admin. Его функционал будет заменён, поэтому можете удалить и само действие. Мы сделаем так, чтоб каждый смог управлять своими записями, в том числе и удалять их. Действие create. В самом начале происходит проверка наличия отправленных пользователем данных. Если таковые присутствуют то они вносятся в базу, в ином случае - обрабатывается шаблон "create". Он содержит в себе пару ссылок и вызов шаблона "_form". Отображению "_form", в свою очередь, передаётся параметр update. Почти такой-же код есть и в шаблоне обновления сообщения. Вообщем, здесь для двух действий используется одна и та же форма, только передаются ей, при обработке, разные значения параметра "update". Код кнопок можете спокойно затирать, оставьте лишь вызов формы. А код отображаемого шаблона _form заменим на следующий. Код HTML:
<?if($update):?>количество просмотров. Добавим их в POST-массив перед помещением данных в модель, и уже всё вместе занесём в БД. Вот код который должен быть вызван в том случае если массив $_POST["Records"] обнаружен. PHP код:
записи (ссылка типа /records/show/id/5/). Метод actionShow. Он отображает запрошенную запись, в зависимости от указанного id. Его код состоит из одной строки. В ней вызывается соответствующий шаблон, принимая результат работы метода loadRecords. В отображении этот результат обрабатывается, и полученные данные выводятся пользователю. Всё идеально, но есть небольшая загвоздка. В данных сообщения нет одного - имени автора. Есть только его идентификатор (поле author_id). Давайте настроим связь между моделями Records и Users так, чтоб при запросе одной или нескольких записей автоматически запрашивались имена их авторов ( http://www.yiiframework.com/doc/guide/ru/database.arr#declaring-relationship ). Для этого в первой модели найдите метод "relations" и в возвращаемый им массив внесите ячейку "author", куда будет помещена связь со второй моделью. PHP код:
В отображение все эти данные поступят вместе с остальными, так что нам нужно всего лишь напечатать свойство "$model->author->login". Вот полный код шаблона show. Код HTML:
<?if($model === null):?>Метод actionList - просмотр списка записей. Разберём всё что в нём делается. Сначала создаётся объект класса CDbCriteria ( http://www.yiiframework.com/doc/api/CDbCriteria ). С помощью него, при выборке данных из базы, указывается сколько записей нужно выбрать ( количество указано в константе PAGE_SIZE нашего контроллера ). Затем эти данные извлекаются. Они передаются в отображение и выводятся на экран. В конце создаётся объект класса CPagination ( http://www.yiiframework.com/doc/api/CPagination ), отвечающий за разбиение материала на страницы. В самом действии почти ничего не нужно менять. Надо внести лишь 2 небольших изменения. Во-первых, значение константы PAGE_SIZE измените на 3. Во-вторых изменим код самого контроллера так, чтобы он показывал список не всех сообщений, а того пользователя, чей идентификатор передан в параметре "user_id" ( ссылка будет выглядеть вот так - http://yii/records/list/user_id/3 ). В самое начало кода добавим обработку поступившего номера пользователя. PHP код:
PHP код:
Для того чтоб получить имя автора можно написать в модели соответствующую функцию, вызвать её, передав в качестве исходных данных номер пользователя в базе, и результат отдать в отображение. А можно взять его сразу из массива сообщений ещё до их обработки. Например, из нулевой записи PHP код:
На очереди шаблон "list". Сотрите из него весь код и внесите туда вот что. Код HTML:
<h2>Список сообщений пользователя <?=$models[0]->author->login;?></h2><br />первых символов текста. Можете сейчас пройти по ссылке http://yii/records/list/user_id/5 и Вы увидите блог пользователя Николай. В правом нижнем углу страницы можно заметить перекорёженое изображение постраничной навигации. Оно выводится виджетом CLinkPager. Здесь мы напоролись на один из минусов Yii. По каким-то причинам отображений у CLinkPager нет. HTML-код, который Вы видите, находится прямо в PHP-коде виджета. Исправим это. Откройте файл ClinkPager.php, находящийся в директории /base/framework/web/widgets/pagers/. Нас интересует методы run и createPageButton. Первый собирает общий html-код и выводит его на экран. Второй - формирует код кнопок. Переделаем код под более-менее стандартный вид. Для этого мы создадим дерикторию views в папке с виджетом, и поместим туда 2 шаблона. Первый - pageButton.php. Он содержит код одной ссылки на страницу. Код HTML:
<?if(!$hidden):?>Код HTML:
<br />затем сам тег собирается и возвращается в виде результата. Заменим всё это одной строкой. Возвратим обработанный шаблон нашей кнопки, куда передадим все поступившие в функцию данные. В этом нам поможет метод renderPartitional ( http://www.yiiframework.com/doc/api/CController#renderPartial-detail ), класса CController - он не выводит обработанное отображение, а возвращает его. PHP код:
ему код кнопок. PHP код:
перевод слов типа Next, Last и т.д. Для этого откроем наш языковой файл и внесём туда следующие ячейки. PHP код:
PHP код:
Изменение записей. Редактирование сообщений осуществляется через метод actionUpdate. Как Вы помните из описания метода actionCreate, он использует форму "_form". Единственное, что здесь требует редактирования, это шаблон update. Удалите там всё кроме вызова формы. PHP код:
одну строку. PHP код:
Действие delete. В нём требуется только вставить проверку авторства пользователя и исправить редирект после удаления. Для этого мы в начало метода внесём следующий код. PHP код:
PHP код:
|
Комментарии.
На нашем сайте пользователи (как авторизированные так и неизвестные) должны иметь возможность комментировать каждую запись. Для этого мы создадим контроллер Comments. По аналогии с контролером записей нужно воспользоваться утилитой yiic и командами model и crud. После создания контроллера откройте его и подредактируйте правила доступа следующим образом. В разрешённые всем действия добавьте create. Действия update, delete и admin удалите. Представим что всех их будет выполнять либо администратор ресурса, либо владелец блога. Затем откройте отображение show, контроллера Records. После кода отображения записи поместите код формы, в которую посетитель будет вносить текст комментария. Код HTML:
<br />Но в форме у нас всего два поля - комментарий и номер записи. А в таблице должны быть заполнены ещё столько же - дата публикации и идентификатор автора. Поэтому, прямо перед передачей POST-параметров в модель PHP код:
время в формате UNIX TIMESTAMP. PHP код:
показать посетителю не именно то что он оставил, а комментируемую запись и все сообщения комментаторов. Для этого мы перебросим его на метод show контроллера create, поместив в ссылку номер комментируемой записи. PHP код:
в методе actionShow, получить список отзывов о записи (например, описать для этого соответствующую функцию в модели Comments). А можно настроить ещё одну связь в модели Records с моделью комментариев. Мы пойдём вторым путём и в массив, возвращаемый методом relations поместим вот такую ячейку. PHP код:
post_id. Все они будут помещаться в итоговую модель, в соответствующую ячейку. Но в самих комментариях нам нужно отображать ещё и имя их автора. Для этого применим связь которую уже объявляли при работе с записями - свяжем модель комментариев и модель пользователей по полю author_id. PHP код:
Код HTML:
<br /><br /><br />Кэширование. Ну и под конец коснёмся темы кэширования. Оно в Yii ( http://www.yiiframework.com/doc/guide/ru/caching.overview ) может быть реализовано с помощью пяти компонентов - memCache, ACP, XCache, EAcceleratior и CDbCache. Для всех них создан один уникальный класс-оболочка - CCache ( http://www.yiiframework.com/doc/api/CCache#get-detail ). Через него можно работать со всеми пятью компонентами через один и тот же интерфейс. Мы воспользуемся кэшированием с использованием базы данных ( CDbCache ). Для активизации компонента требуется открыть главный конфигурационный файл, и в массив ячейки "components", добавить ячейку "cache" со следующим содержимым PHP код:
- http://www.yiiframework.com/doc/guide/ru/caching.data ). Задействовать нам нужно всего 3 метода - get, set и delete. Они принадлежат объекту возвращаемому Yii::app()->cache. В качестве основного параметра им нужно передать специальный идентификатор ( обычное имя под которым кусок информации будет записан, удалён или получен из кэша ). Из названий этих методов понятно что первый проверяет наличие определённых данных, второй эти данные устанавливает, а третий - удаляет. Откроем контроллер ответственный за записи в блогах и обратимся к методу actionShow. В нём мы будем кэшировать данные поступающие из базы. Изменим код следующим образом. В начале мы получим номер запрашиваемой записи - он находится в параметре id. Далее, мы проверим - если кэш записи уже есть, то достанем его и передадим в отображение. Если нет - вызовем метод loadRecords, сохраним в кэше его результат и передадим в отображение. Ничего сложного. PHP код:
У нас они находятся в действиях редактирования и удаления. В "update" мы заменим код PHP код:
PHP код:
PHP код:
Теперь рассмотрим работу с фрагментом страницы ( http://www.yiiframework.com/doc/guide/ru/caching.fragment ). Это ещё проще. Здесь задействуются методы beginCache и endCache класса CController (то есть можно будет к нему обращаться в отображении через $this). Мы должны вызвать их в начале и в конце того куска страницы который должен быть записан. При обращениях пользователей, если фрагмент уже находится в кэше он будет извлечён и показан. Если же нет, то он выполнится и запишется. Этим фрагментом будет код отвечающий за показ комментариев в отображении records/show. В качестве кэш-идентификатора у нас будет фраза "comments_page_номер_страницы". Прямо перед заголовком "Комментарии" поместите следующий код: PHP код:
PHP код:
PHP код:
Заключение. На мой взгляд Yii, в отличие от многих других фреймворков, является инструментом с высоким порогом вхождения. Понять его основы, логику, принципы и зависимости в начале довольно трудно. Так же мне кажется что утверждение разработчиков о том, что Yii можно использовать для любых приложений, не верно. Всё-таки он больше подходит именно для веб-2.0-приложений ( как его позиционируют например на сайте журнала phpInside ). Если разобраться то оказывается что по функционалу фреймворк очень хорош, и является одновременно мощным и простым. Если в процессе чтения статьи у Вас что-то не получилось то Вы можете взять готовый код экспериментального приложения в архиве ready.zip. Удачи Вам в Ваших проектах! |
Кто нибудь осилил ?
|
Полезная статья о хорошем фреймворке =)
Кстати...к слову о rules() в моделе... Если требуется проверить длинну и вывести соответствующее сообщение при не выполнении условия, то это делается так: PHP код:
|
Спасибо! Буду знать =)
|
| Время: 11:01 |