Yii2: Простое приложение c AngularJS фронтендом. Серверная часть

Теперь, когда все подготовительные работы закончены, можно всерьез заняться нашим приложением. PHP фреймворк Yii 2.0 позволяет быстро и просто создать необходимый нам функционал, включая RESTful api.

Забыл сказать, в этом учебном приложении мы реализуем простой каталог фильмов. Данные каталога будем хранить в базе данных mysql.

Структура базы данных

Создадим базу данных yii2-ang и добавим в нее таблицу film со следующей структурой:

  • id — int(11)
  • title — varchar(255)
  • storyline — text
  • director — varchar(100)
  • year — int(4)

Пример скрипта для создания новой базы данных, таблицы и заполнения ей первоначальными данными:

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

CREATE DATABASE IF NOT EXISTS `yii2-ang` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `yii2-ang`;

CREATE TABLE IF NOT EXISTS `film` (
 `id` int(11) NOT NULL,
 `title` varchar(255) NOT NULL,
 `storyline` text,
 `director` varchar(100) NOT NULL,
 `year` int(4) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4;

INSERT INTO `film` (`id`, `title`, `storyline`, `director`, `year`) VALUES
(1, 'Побег из Шоушенка', 'Успешный банкир Энди Дюфрейн обвинен в убийстве собственной жены и ее любовника. Оказавшись в тюрьме под названием Шоушенк, он сталкивается с жестокостью и беззаконием, царящими по обе стороны решетки. Каждый, кто попадает в эти стены, становится их рабом до конца жизни. Но Энди, вооруженный живым умом и доброй душой, отказывается мириться с приговором судьбы и начинает разрабатывать невероятно дерзкий план своего освобождения.', 'Фрэнк Дарабонт', 1994),
(2, 'Зеленая миля', 'Обвиненный в страшном преступлении, Джон Коффи оказывается в блоке смертников тюрьмы «Холодная гора». Вновь прибывший обладал поразительным ростом и был пугающе спокоен, что, впрочем, никак не влияло на отношение к нему начальника блока Пола Эджкомба, привыкшего исполнять приговор.\r\n\r\nГигант удивил всех позже, когда выяснилось, что он обладает невероятной магической силой…', 'Фрэнк Дарабонт', 1999),
(3, 'Форрест Гамп', 'От лица главного героя Форреста Гампа, слабоумного безобидного человека с благородным и открытым сердцем, рассказывается история его необыкновенной жизни.\r\n\r\nФантастическим образом превращается он в известного футболиста, героя войны, преуспевающего бизнесмена. Он становится миллиардером, но остается таким же бесхитростным, глупым и добрым. Форреста ждет постоянный успех во всем, а он любит девочку, с которой дружил в детстве, но взаимность приходит слишком поздно.', 'Роберт Земекис', 1994),
(4, 'Список Шиндлера', 'Фильм рассказывает реальную историю загадочного Оскара Шиндлера, члена нацистской партии, преуспевающего фабриканта, спасшего во время Второй мировой войны почти 1200 евреев.', 'Стивен Спилберг', 1993),
(5, '1+1', 'Пострадав в результате несчастного случая, богатый аристократ Филипп нанимает в помощники человека, который менее всего подходит для этой работы, — молодого жителя предместья Дрисса, только что освободившегося из тюрьмы. Несмотря на то, что Филипп прикован к инвалидному креслу, Дриссу удается привнести в размеренную жизнь аристократа дух приключений.', 'Оливье Накаш', 2011),
(6, 'Король Лев', 'У величественного Короля-Льва Муфасы рождается наследник по имени Симба. Уже в детстве любознательный малыш становится жертвой интриг своего завистливого дяди Шрама, мечтающего о власти.\r\n\r\nСимба познаёт горе утраты, предательство и изгнание, но в конце концов обретает верных друзей и находит любимую. Закалённый испытаниями, он в нелёгкой борьбе отвоёвывает своё законное место в «Круге жизни», осознав, что значит быть настоящим Королём.', 'Роджер Аллерс', 1994),
(7, 'Леон', 'Профессиональный убийца Леон, не знающий пощады и жалости, знакомится со своей очаровательной соседкой Матильдой, семью которой расстреливают полицейские, замешанные в торговле наркотиками. Благодаря этому знакомству он впервые испытывает чувство любви, но…', 'Люк Бессон', 1994),
(8, 'Начало', 'Кобб — талантливый вор, лучший из лучших в опасном искусстве извлечения: он крадет ценные секреты из глубин подсознания во время сна, когда человеческий разум наиболее уязвим. Редкие способности Кобба сделали его ценным игроком в привычном к предательству мире промышленного шпионажа, но они же превратили его в извечного беглеца и лишили всего, что он когда-либо любил. \r\n\r\nИ вот у Кобба появляется шанс исправить ошибки. Его последнее дело может вернуть все назад, но для этого ему нужно совершить невозможное — инициацию. Вместо идеальной кражи Кобб и его команда спецов должны будут провернуть обратное. Теперь их задача — не украсть идею, а внедрить ее. Если у них получится, это и станет идеальным преступлением. \r\n\r\nНо никакое планирование или мастерство не могут подготовить команду к встрече с опасным противником, который, кажется, предугадывает каждый их ход. Врагом, увидеть которого мог бы лишь Кобб.', 'Кристофер Нолан', 2010),
(9, 'Бойцовский клуб', 'Терзаемый хронической бессонницей и отчаянно пытающийся вырваться из мучительно скучной жизни, клерк встречает некоего Тайлера Дардена, харизматического торговца мылом с извращенной философией. Тайлер уверен, что самосовершенствование — удел слабых, а саморазрушение — единственное, ради чего стоит жить.\r\n\r\nПройдет немного времени, и вот уже главные герои лупят друг друга почем зря на стоянке перед баром, и очищающий мордобой доставляет им высшее блаженство. Приобщая других мужчин к простым радостям физической жестокости, они основывают тайный Бойцовский Клуб, который имеет огромный успех. Но в концовке фильма всех ждет шокирующее открытие, которое может привести к непредсказуемым событиям…', 'Дэвид Финчер', 1999),
(10, 'Интерстеллар', 'Когда засуха приводит человечество к продовольственному кризису, коллектив исследователей и учёных отправляется сквозь червоточину (которая предположительно соединяет области пространства-времени через большое расстояние) в путешествие, чтобы превзойти прежние ограничения для космических путешествий человека и переселить человечество на другую планету.', 'Кристофер Нолан', 2014);

ALTER TABLE `film`
ADD PRIMARY KEY (`id`);

ALTER TABLE `film`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=14;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

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

Подключение базы данных

Для настройки базы данных в базовом приложении нужно указать параметры подключения к ней в файле server/config/db.php:

<?php

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2-ang', // Хост и название базы данных
    'username' => 'yii2-ang', // Имя пользователя mysql
    'password' => '********', // Пароль пользователя mysql
    'charset' => 'utf8',
];

Создание модели

В качестве помощи, при создании модели, можно использовать генератор кода gii.

В итоге, файл server/models/Film.php  должен иметь примерно следующее содержание:

<?php

namespace app\models;
use Yii;

class Film extends \yii\db\ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'film';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['title', 'director', 'year'], 'required'],
            [['storyline'], 'string'],
            [['year'], 'integer'],
            [['title'], 'string', 'max' => 255],
            [['director'], 'string', 'max' => 100]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'title' => 'Title',
            'storyline' => 'Storyline',
            'director' => 'Director',
            'year' => 'Year',
        ];
    }
}

Реализация RESTful api

Если вы не знакомы с особенностями поддержки rest в yii2, обратитесь документации.

Создание REST контроллера

Встроенный в Yii 2.0 генератор кода gii не поддерживает автоматическое создание crud для rest. Сделаем это сами.

Для начала, создадим файл FilmController.php в каталоге server/controllers, примерно следующего содержания:

namespace app\controllers;

use yii\rest\ActiveController;

class FilmController extends ActiveController
{
    // указываем класс модели, который будет использоваться
    public $modelClass = 'app\models\Film';

    public function behaviors()
    {
        return 
        \yii\helpers\ArrayHelper::merge(parent::behaviors(), [
            'corsFilter' => [
                'class' => \yii\filters\Cors::className(),
            ],
        ]);
    }
}

Класс контроллера должен наследоваться от yii\rest\ActiveController. Свойство modelClass позволяет указать модель app\models\Film , которая будет использоваться для работы с данными.

Поведение cors добавлено для возможности доступа к данным посредством ajax запросов с других доменов.

Настройка ссылок

Внесем изменения в настройки базового приложения. Изменим конфигурацию компонента urlManager в файле server/config/web.php :

'urlManager' => [
    'enablePrettyUrl' => true,
    'enableStrictParsing' => true,
    'showScriptName' => false,
    'rules' => [
        ['class' => 'yii\rest\UrlRule', 'controller' => 'film'],
    ],
],

Мы добавили URL правило для контроллера film для того, что бы можно было обращаться к данным используя красивые (человеко-понятные ссылки). В случае нескольких контроллеров, они задаются массивом:

'rules' => [
    ['class' => 'yii\rest\UrlRule', 'controller' => ['film','actor','genre']],
],

Для активации красивых ссылок, нужно добавить файл server/web/.htaccess  , включающий mod_rewrite в apache:

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php [L]

В случае использования веб-сервера nginx, этот файл не нужен.

Включение приема JSON данных

По-умолчанию, api принимает только запросы типов application/x-www-form-urlencoded и multipart/form-data.

Для активации json запросов, нужно указать парсеру соответствующий компонент:

'components' => [
    'request' => [
    ...
        'parsers' => [
            'application/json' => 'yii\web\JsonParser',
        ],
    ],
...

Контроль

Наш RESTful api готов и мы можем проверить его в работе. Открыв в браузере http://server.local/films, мы видим ответ в виде json на get запрос, перечень всех фильмов:

yii2 restful rest

Какие варианты запросов мы имеем

  • GET /films: Получить все фильмы;
  • HEAD /films: Получить заголовок ответа на запрос GET /films;
  • POST /films: Создать новый фильм;
  • GET /films/123: Получить данные фильма с id=23;
  • HEAD /films/123: Получить заголовок ответа GET /films/123;
  • PATCH /films/123 и PUT /films/123: Изменить данные фильма с id=123;
  • DELETE /films/123: Удалить фильм с id=123;
  • OPTIONS /films: Получить список доступных методов запроса для /films;
  • OPTIONS /films/123: Получить список доступных методов запроса для /films/123.

Уже на данном этапе возможно поэкпериментировать с RESTful api. Одним из самых доступных инструментов является Postman Chrome Extension:

yii2 rest postman

 

Заключение

Сегодня мы создали простое RESTful api на базе yii2 приложения basic. В дальнейшем будем использовать его из клиентской части приложения.

Введение;
Подготовка;
Серверная часть;
Клиентская часть 1;
Клиентская часть 2.

9 thoughts on “Yii2: Простое приложение c AngularJS фронтендом. Серверная часть

  1. Guest

    Не могли бы вы описать как проводиться аутентификация через RESTful . Какие манипуляции надо провести, а то в документации так поверхностно описано. Желательно с angularjs

    1. iiifx

      Это и есть XML. Но так отображается лишь для браузера. Yii2 в такой конфигурации может отдавать и json, и xml. Как именно отобразить данные бекенд определяет на основе полученных заголовков в запросе

    1. Василий

      В моем случае был виноват Apache. Были не совсем правильно выставлены настройки.

  2. Денис

    Какой смысл указывать в таблице кодировку utf8mb4? Если кодировка соединения utf8. Можете столкнуться со случайной потерей данных, если будете сохранять в таблицу например смаилы.

    «Если вдруг символы с четырехбайтовым представлением в UTF-8 появляются в колонке, которая определена как utf8mb3, то такой символ просто заменяется на знак вопроса (при условии set names utf8mb4, если используется utf8mb3, то строка внезапно обрежется по такому символу).»

    https://habrahabr.ru/company/mailru/blog/235209/#comment_7931895

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *