Добро пожаловать в Cake! Возможно вы просматриваете это обучение, потому что хотите узнать больше о том как работает Cake. Это наша цель, увеличить продуктивность и сделать написание кода более приятным: мы надеемся вы осознаете это, когда углубитесь в код.
Это обучение проведет вас через создание простого приложения блогов. Мы будем доставать и устанавливать Cake, создавая и настраивая базу данных, создавать достаточно кода приложения, чтобы просматривать, добавлять, редактировать и удалять посты в блоге.
Вот, что вам понадобится:
Работающий веб-сервер. Мы будем предполагать, что вы используете Apache, хотя иструкции также должны подойти и к другим серверам. Возможно нам придется еще немного поковыряться в настройках сервера, но большинство достают Cake и запускают его вообще без каких-либо настроек.
Сервер базы данных. Мы собираемся использовать mySQL в этом обучении. Вам нужно знать достаточно об SQL чтобы создать базу данных.
Базовые знания PHP. Чем больше объекто-ориентированого программирования было в вашей жизни, тем лучше: но бойтесь если вы фанат процедурного программирования.
Наконец, вам нужны базовые знания MVC шаблонного программирования. Быстрый обзор можно найти в главе Основные концепции, Раздел 2: MVC. Не волнуйтесь там половина страницы или около того.
Давайте начнем!
Достаем Cake
Сначала давайте достанем копию свеженького кода Cake. Самый последний релиз на момент этой документации это Cake PHP 1.0.1.2708.
Для скачивания посетите проект Cake PHP на Cakeforge: http://cakeforge.org/projects/cakephp/ и закачайте стабильный релиз.
Также можете посмотреть здесь: https://svn.cakephp.org/repo/trunk/cake/1.x.x.x/
Не важно как вы закачали, поместите код в ваш Document Root. Директория должна выглядить как-то так:
Теперь неплохо будет узнать немного о том, как работает структура директории Cake: взгляните на Главу «Основные концепции» Раздел 3: Обзор размещения файлов Cake.
Создание базы данных блога
Далее, давайте настроем основную базу данных для нашео блога. Сейчас, мы просто создадим простую таблицу для хранения постов. Мы также вкинем туда несколько постов, чтобы ипользовать их в целях тестирования. Выполните следующий запрос SQL в вашей базе данных:
/* Сначала, создайте таблицу постов: */
CREATE TABLE posts (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50),
body TEXT,
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);
/* Затем вставим пару постов для тестирования: */
INSERT INTO posts (title,body,created)
VALUES ('The title', 'This is the post body.', NOW());
INSERT INTO posts (title,body,created)
VALUES ('A title once again', 'And the post body follows.', NOW());
INSERT INTO posts (title,body,created)
VALUES ('Title strikes back', 'This is really exciting! Not.', NOW());
Выбор имен таблицы и колонок не случаен. Если вы следуете соглашению о присвоении имен баз данных Cake, и соглашению о присвоении имен классов Cake (оба выделены в дополнении «Соглашение Cake»), вы сможете получить выгоду из множества бесплатной функциональности и избежать настройки. Cake достаточно гибкий, чтобы совладать с самой страшной схемой базы данных, но твердое поддерживание соглашения сохранит ваше время.
Посмотрите на Соглашение Cake для справки, но достаточно сказать, что название таблицы 'posts' автоматически привязывает ее к модели Post, а поля названные 'modiefied' и 'created' автоматически будут управляться Cake'ом.
Настройка базы данных Cake
Давайте сообщим Cake где находится наша база данных и как с ней связаться. Это будет первый и последний этап, где вы что-либо настраиваете.
Копия конфигурации базы данных находится в /app/config/database.php.default. Скопируйте этот файл в ту же директорию, только переименуйте в database.php.
Конфиг-файл должен быть достаточно понятным: просто замените значения в масиве $default теми, что применены к вашей настройке. Образец завершенного массива настроек может выглядить как следующий:
Когда вы сохранили ваш новый файл database.php, вы можете открыть свой браузер и увидеть приветственную страницу Cake. Она также должна сообщить вам, что файл соединения с базой данных найден, и что Cake может успешно связываться с базой.
Заметка о mod_rewrite
Если приветсвенная страница Cake выгядит слегка смешно (без изображений или стилей css), это скорее всего значит, что mod_rewrite не работает на вашей системе. Вот несколько советов как заставить его работать:
Убедитесь, что подмена .htaccess разрешена: в вашем httpd.conf, у вас должна быть секция, которая определяет секцию для каждой директории на вашем сервере. Убедитесь, что Allow Override установлен на All для правильной директории.
Убедитесь, что вы редактируете системный httpd.conf, а не пользовательский или определенного сайта.
По тем или иным причинам, у вас может быть копия Cake PHP в которой нету .htaccess. Это иногда случается потому, что некоторые операционные системы воспринимают файлы с точкой перед именем, как скрытые и не копирует их. Убедитесь, что ваша копия Cake PHP скачана с надежного источника, то есть у нас.
Убедитесь, что вы правильно загружаете mod_rewrite! У вас должно быть что-то вроде Load Module rewrite_module libexec/httpd/mod_rewrite.so и Add Module mod_rewrite.c в вашем httpd.conf.
Если вы не хотите или не можете заставить mod_rewrite (или подобный модуль) работать на вашем сервере, вам нужно использовать встроенные красивые ссылки Cake. В /app/config/core.php разкоментируйте линию, которая выглядит так:
<? define ('BASE_URL', env('SCRIPT_NAME')); ?>
Это сделает ваши ссылки похожими на www.example.com/index.php/controllername/actionname/param или www.example.com/controllername/actionname/param.
Создание модели Post
Класс модели это хлеб и масло приложений Cake PHP. Создавая модель Cake, которая будет взаимодействовать с нашей базой данных, мы получим потребность в создании операций «показать», «добавить», «редактировать», и «удалить».
Файлы класса модели Cake здесь /app/models, а файл который мы будем создавать будет сохранен в /app/models/post.php. Завершенный файл должен выглядить так:
/app/models/post.php <?php
class Post extends AppModel { var $name = 'Post'; }
?>
В связи со способом, по которому классу и файлу даны имена, это говорит Cake'у, что вы хотите чтобы модель Post была доступна в вашем Post Controller, который связан с таблицей в вашей базе данных 'posts'.
Переменная $name всегда стоит того, чтобы ее добавили, и используется чтобы совладать с некоторыми именами классов в PHP4.
Больше о моделях, таких как префиксы таблиц, колбеки и верификация, посмотрите главу Модели.
Создание контроллера постов
Дальше мы создадим контроллер для наших постов. Контроллер это то, где будет весь код для взаимодействия с постами, и он также находится там где и все действия для этой модели. Вам нужно разместить этот новый контроллер в файл под названием posts_controller.php в вашем каталоге /app/controllers. Вот как должен выглядить основной контроллер:
/app/controllers/posts_controller.php <?php
class PostsController extends AppController { var $name = 'Posts'; }
?>
Теперь давайте добавим действие в наш контроллер. Когда пользователи запришивают www.example.com/posts, это то же, что и запрос www.example.com/posts/index. С тех пор как мы хотим, чтобы пользователи могли просматривать список постов, когда они приходят по этой ссылке, действие index будет выглядить как это:
/app/controllers/posts_controller.php (действие index добавлено) <?php
class PostsController extends AppController { var $name = 'Posts';
function index() { $this->set('posts', $this->Post->findAll()); } }
?>
Позвольте мне немного пояснить действие. После определения функции index() в нашем Posts Controller, пользователи могут получить доступ к коду запрашивая www.example.com/posts/index. Также, если бы мы определили функцию foobar(), пользователи могли бы получить доступ по адресу www.example.com/posts/foobar.
Простое указание в действие использует set() для вставки данных в отображение (которое мы создадим следующим). Устанавливается переменная отображения 'posts' еквивалентная возвращаемому значению метода findAll() модели Post. Наша модель Post автоматически доступна в $this->Post, потому что мы следили соглашению Cake по присвоению имен.
Узнать больше о контроллерах Cake можно в главе Контроллеры.
Создание отображений постов
Теперь когда у нас есть наша база данных соединена использованием нашей модели, а наш код приложения определен нашим контроллером, давайте создадим отображение для действия index, которое мы определили выше.
Отображения Cake это просто фрагменты HTML и PHP, которые устанавливаются в разметку приложения. Разметки можно определять и переключаться между ними, но пока, давайте просто использовать стандартную.
Помните в последнем разделе как мы назначали переменную 'posts' в отображении используя метод set()? Это будет передавать данные в отображение, которое будет выглядить как это:
Файлы отображений Cake хранятся в /app/views внутри каталога названного в честь контроллера к которому они принадлежат (мы должны создать каталог 'posts' в таком случае). Для форматирования данных постов в приятную таблицу, наш код отображения может выглядить так:
Возможно вы заметили использование объекта названного $html. Это отдельный пример из класса Html Helper. Хелперы помогают делать ссылки, формы, Java Script и Ajax. Подробнее о хелперах в... вы угадали, в главе Хелперы, но что важно заметить здесь это то, что метод link() сгенерирует ссылки HTML с данным заголовком (первый параметр) и данным адресом (второй параметр).
Когда определяете ссылки в Cake, вы просто даете путь относящийся к базе приложения, а Cake заполняет оставшееся. То есть, ваши ссылки будут принимать форму /controller/action/id.
Теперь вы можете направить свой браузер на http://www.example.com/posts/index. Вы должны увидеть отображение, коректно сформатированное с заголовком и таблицей со списком постов.
Если вы нажмете на одну из ссылок, которые мы создали в этом отображении (эта ссылка это заголовок поста с адресом /posts/view/some_id), вы наверняка будете осведомлены Cake'ом, что действие еще не определено. Если вы не будете проинформированы, или что-то пошло не так, или же вы уже определили действие, в последнем случае вы подлец. В любом случае, мы создадим его сейчас:
Запрос set() должен казаться знакомым. Заметьте мы используем read() а не findAll(), потому что мы хотим получить информацию только об одном посте.
Заметьте что действие нашего отображение берет параметр. Этот параметр передан в приложение запросом URL. Если пользователь запрашивает /posts/view/3, тогда значение 3 будет вставлено как $id.
Теперь давайте создадим отображение для нашего нового действия 'view' и разместим в /app/views/posts/view.thtml.
Проверьте работает ли это, пройдя по ссылкам /posts/index или запросом поста /posts/view/1.
Добавление постов
Чтение постов из базы данных и показывание их нам это конечно хорошо, но давайте позволим добавление новых постов.
Во-первых, начнем с действия add() в Posts Controller:
/app/controllers/posts_controller.php ( действие add добавлено) <?php
class PostsController extends AppController { var $name = 'Posts';
function index() { $this->set('posts', $this->Post->findAll()); }
function view($id) { $this->Post->id = $id; $this->set('post', $this->Post->read());
}
function add() { if (!empty($this->data)) { if ($this->Post->save($this->data)) { $this->flash('Your post has been saved.','/posts'); } } } }
?>
Позвольте мне прочесть вам действие add() в простом языке: если данные формы не пустые, попробовать сохранить модель поста использовав эти данные. Если по каким-то причинам данные не сохраняются, выдать мне ошибки верификации данных и отрендерить отображение с показом этих ошибок.
Когда пользователь использует форму для отправки данных в ваше приложение, эта информация доступна в $this->params. Вы можете вывести их с помощью pr() если хотите увидеть их. $this->data это псеводоним для $this->params['data'].
Функция $this->flash() это функция контроллера, которая отображает сообщения пользователю на секунду (используя разметку для флеш-сообщений) потом перенаправляет пользователя по другому адресу (/posts, в нашем случае). Если DEBUG стоит на 0 $this->flash() переадресует автоматически, однако, если DEBUG на 0 вы сможете увидить флеш верстку и кликнуть на сообщении чтобы управлять переадресацией.
Вызываемый метод save() проверит наявность верификационных ошибок и не сохранит данные если таковые присутствуют. Доступно несколько методов, которыми вы сможете проверить верификационные ошибки, но мы немного поговорим о запросе validateErrors(), так что будьте на связи, когда я расскажу как выглядит отображение, а пока мы переходим к разделу о верификации данных.
Верификация данных
Cake уничтожает монотонность созданий проверок в форме. Все ненавидят прописывать бесконечные формы с их проверками, а Cake делает это легко и быстро.
Чтобы воспользоваться преимуществами возможностей проверки, вам надо использовать HTML хелпер в вашем отображении. HTML хелпер доступен по умолчанию во всех отображениях в $html.
Как и с $html->link(), $html->url() будет генерировать подходящую ссылку из контроллера и действия, которое мы предоставили. По умолчанию, это выводит тег формы POST, но это можно модифицировать вторым параметром. Функции $html->input() и $html->textarea() убирает элементы формы одинаковых имен. Первый параметр сообщает Cake, к которой модели/полю они относятся, а второй параметр для дополнительных аттрибутов HTML (как размер поля). Снова-таки посмотрите главу Хелперы для подробной информации о хелперах.
Функция tagErrorMsg() выводит сообщения об ошибках в случае появления верификационных проблем.
Если вы хотите обновить свое отображение /app/views/posts/index.thtml чтобы включить новую ссылку Add Post направляющую www.example.com/posts/add.
Выглядит достаточно круто, но как мне сообщить Cake о своих требованиях верификации? Вот где мы возвращаемся к модели.
Массив $validate сообщает Cake как проверять ваши данные когда вызван метод save(). Значение для тех ключей просто константы установленные Cake'ом, который переводит их в регулярные выражения (см. /cake/libs/validators.php). Сейчас проверки Cake'а базируются на регулярных выражениях, но вы так же можете использовать Model::invalidate() чтобы просмотреть свои собственные верификации.
Теперь когда ваши проверки на месте, используйте приложение чтобы попробовать добавить новый пост без заголовка или тела, чтобы глянуть как это работает.
Удаление постов
Теперь давайте создадим возможность пользователям удалять посты. Начнем с действия delete() в Posts Controller:
<? /app/controllers/posts_controller.php (только действие delete) function delete($id) { $this->Post->del($id); $this->flash('The post with id: '.$id.' has been deleted.', '/posts'); } ?>
Этот код удаляет пост определенный по $id, и использует flash() чтобы показать пользователю сообщение подтверждения перед переадрисаций в /posts.
Поскольку мы просто выполняем некий код и переадресовуем, это действие не имеет отображения. Вы можете обновить отображения index чтобы позволить пользователям удалять посты.
Этот код отображения также позволяет использовать Html хелпер, чтобы подсказать пользователю диалог подтверждения Java Script перед попыткой удалить пост.
Редактирование постов
Итак... редактирование поста: начнем-с. Теперь вы профессионал в Cake, так что вы должны были подобрать образец. Сделайте действие, потом отображение. Вот как будет выглядить действие редактирования Posts Controller:
/app/controllers/posts_controller.php (только действие edit) <? function edit($id = null) { if (empty($this->data)) { $this->Post->id = $id; $this->data = $this->Post->read(); } else { if ($this->Post->save($this->data['Post'])) { $this->flash('Your post has been updated.','/posts'); } } } ?>
Это проверяет на наличие отправленных данных формы. Если ничего не отправлено, идем искать пост и отправляем его в отображение. Если какие-то данные были отправлены, пробуем сохранить модель Post (или возвращает назад пользователя и показываем верификационные ошибки).
Это отображение выводит форму редактирования (с заполненными значениями), и нужные сообщения об ошибках (если есть). Одна вещь на заметку: Cake будет подразумевать, что вы редактируете модель если поле 'id' существует в текущей сохраненной модели. Если нет 'id' (оглянитесь на наше отображение добавления), Cake будет подразумевать, что вы вводите новую модель, когда вызываете save().
Теперь вы можете обновить ваше отображение index ссылками на редактирование определенных постов:
Эта часть опциональная, но полезная в понимании как формулируются ссылки к определенным функциям в Cake. Мы собираемся сделать только быстрые изменения в роутах в этом обучающем примере. Для более полной справки смотрите главу «Настройка», Раздел 3: Настройка роутов.
Роут по умолчанию Cake отведет человека, посещающего корень сайта (например http://www.example.com) к Pages Controller'у, и отрендерит отображение под названием home. Вместо этого, мы хотим, чтобы пользователи нашего блога шли к нашему Posts Controller'у, который скоро будет создан.
Роутинг Cake находится в /app/config/routes.php. Вы хотите разкоментировать или удалить линию похожую на эту:
$Route->connect ('/', array('controller'=>'pages', 'action'=>'display', 'home'));
Эта линия связывает ссылку / с домашней страницей Cake по умолчанию. Мы хотим связать ее с нашим собственным контроллером, так что добавьте линию, которая выгляит так:
$Route->connect ('/', array('controller'=>'posts', 'action'=>'index'));
Это должно связывать запрос пользователей '/' с действием index() нашего Posts Controller.
Итог
Создание приложений таким способом выиграет вам время, честь, женщин и деньги и даже ваши самые дикие фантазии. Просто, не так ли? А теперь вспомните, что этот обучающий пример – основы. Cake обладает большим количеством возможностей и является очень гибким. Используйте это руководство как гид для создания более богатых на возможности приложений.
Теперь, когда вы создали начальное приложение, вы готовы к реальным вещам. Начните свой собственный проект, прочтите остальное руководство и API.
Если вам нужна помощь, приходите в #cakephp. Добро пожаловать в Cake!