Статьи

Yii Routing, активная запись и кеширование

Почти у всех современных веб-приложений есть три основные проблемы: легко и эффективно извлекать данные из базы данных, кэшировать веб-контент и переписывать URL-адреса для создания удобных для пользователя URL-адресов. Yii, как и любая другая хорошая структура, предлагает простые и легкие решения для всего вышеперечисленного. В моей предыдущей статье я рассмотрел основы создания простого приложения CRUD с Yii. В этом руководстве мы рассмотрим, как Yii значительно упрощает разработку веб-сайтов, управляемых базой данных, с поддержкой Active Record. Кроме того, Yii позволяет вам еще больше улучшить свои сайты, внедрив удобные для пользователя URL-адреса и мощные методы кэширования. Давайте погрузимся в!

Попав в базу данных

Мы будем создавать очень простое веб-приложение для хранения и получения сведений о различных смартфонах с помощью Yii.

Для создания скелетного приложения Yii мы будем использовать инструмент командной строки yiic Вы можете найти его в YiiRoot/framework Поскольку я нахожусь на окнах, это под C:\yii\framework Я рекомендую добавить этот каталог в системный путь, чтобы вы могли запускать yiic Если вы работаете в Windows, вам также необходимо добавить путь к php.exe

Просто перейдите в папку, где хранятся все ваши PHP-проекты (у меня Windows, поэтому в моем случае это C: \ wamp \ www), а затем выполните команду: yiic webapp project_name_here Я называю проект как магазин гаджетов . Это должно создать новый проект Yii с необходимой иерархией папок.

По умолчанию к действиям Yii, определенным внутри контроллеров, обращаются следующим образом:

http://localhost/gadgetstore/index.php?r=controller/action

Поскольку мы хотим быть удобными для пользователя, нам не нужен этот тип URL. Чтобы изменить это, откройте файл конфигурации, например, main.php

 'urlManager'=>array(        
'urlFormat'=>'path',        
'rules'=>array(
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',        '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
),

Добавьте 'showScriptName'=>falseindex.php Также не забудьте добавить в корневой каталог вашего проекта файл .htaccess

 Options +FollowSymLinks
IndexIgnore */*
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
</IfModule>

Теперь к URL можно получить доступ гораздо проще:

http://localhost/gadgetstore/controller/action

Настройка вашего приложения для использования базы данных — это добавление нескольких строк в вашу конфигурацию. Просто откройте файл /protected/config/main.php

 'db'=>array(
'connectionString' =>'mysql:host=localhost;dbname=testdb',
'emulatePrepare' => true,
'username' => 'root',
'password' => '',
'charset' => 'utf8',
),

Здесь мы в основном настраиваем наше приложение для использования конкретной базы данных MySQL или MariaDB. В моем случае имя базы данных — testdb Измените имя базы данных в приведенном выше фрагменте соответственно. Остальные детали говорят сами за себя.

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

Структура таблицы следующая:

 Table Name: phone

Column        Type    
id            int(10)    
name          varchar(65)    
price          int(6)    
memory          varchar(65)    
camera          varchar(65)    
screen_size   varchar(65)    
os          varchar(65)

В настоящее время мы просто оставим 5 простых атрибутов, общих для всех смартфонов, таких как цена, память, камера, screen_size и os.

Теперь следующим шагом является создание класса Active Record, который будет содержать атрибуты смартфона. Каждый класс AR соответствует таблице базы данных, и каждый экземпляр AR представляет одну строку в этой таблице. Теперь давайте создадим класс AR с именем Phone. Для создания этого класса мы будем использовать gii, инструмент автоматической генерации кода, который поставляется вместе с Yii. Откройте: http://localhost/gadgetstore/gii Укажите имя таблицы (в моем случае phone Посмотрите на следующий скриншот.

Теперь нажмите «Предварительный просмотр» и нажмите «Создать», чтобы создать класс модели. Вы можете найти его в каталоге protected/models

Когда класс AR сгенерирован, вы можете создать его в любом месте и получить доступ к атрибутам таблицы базы данных в качестве свойств экземпляра AR. Это достигается с помощью магического метода __get() Например, совершенно законно делать следующее:

 $model=new Phone;   //creates new model instance
$model->name="Samsung Galaxy Note 3"; //sets name property
$model->price=299;    //sets price property
$model->os="Android 4.3"; //sets os property

Теперь, чтобы сохранить модель, все, что вам нужно сделать, это вызвать save () для нее.

 $model->save(); //saves the phone to the database.

Обновление существующей строки также очень просто.

 $model=Phone::model()->findByPK(10);  //phone with id 10
$model->price=300;
$model->save(); //save the updates in DB.

Чтобы удалить строку:

 $model=Phone::model()->findByPK(10);  
$model->delete(); //gone from the table

Active Record в основном предлагает простой способ выполнения операций CRUD, которые часто включают простые команды SQL. Для сложных запросов вы можете переключиться на Yii DAO .

Требуется небольшое изменение в сгенерированной модели. Откройте класс модели Phone и найдите следующую строку в функции rules()

 array('id, name, price, memory, camera, screen_size, os', 'safe', 'on'=>'search')

Теперь замените searchinsert Почему мы это сделали, станет ясно в следующих разделах.

Теперь, когда у вас есть готовый AR, нам нужно создать контроллер, который будет фактически вставлять / обновлять (также называемый upsert) в базе данных, используя класс AR. Просто создайте файл PhoneController.php Внутри файла создайте пустой класс PhoneController.

 class PhoneController extends Controller{

}

Теперь давайте добавим функцию actionAdd()

 public function actionAdd(){
    $model=new Phone;
    if(isset($_POST['Phone'])) //line 3
    {
        $model->attributes=$_POST['Phone']; //line 5
        if($model->validate()){
          $model->save();
          $this->redirect("view/$model->id"); //line 6
        }
    }
    $this->render('add',array('model'=>$model));
}

В этой функции мы добавляем новую строку в таблицу. Но перед этим нам нужно создать файл представления, который показывает форму, через которую можно вводить различные значения атрибутов телефона. Форма может быть очень легко сгенерирована с помощью генератора форм gii. Вы можете открыть gii в своем браузере и перейти к генератору форм. Просто введите название модели (Phone) и название вида (в данном случае phone / add) и нажмите кнопку «Создать». Это создаст файл представления add.phpprotected/views/phone

В приведенном выше фрагменте сначала мы проверяем, является ли запрос POST. Если нет, то мы просто показываем форму, где пользователь может вводить значения. Но если это сообщение назад, нам нужно сохранить данные в таблице. Для захвата входящих данных мы делаем следующее:

 $model->attributes=$_POST['Phone'];

Вышеуказанная операция называется массовым присваиванием. Здесь всем свойствам модели присваиваются значения, полученные в запросе. Помните, как мы изменили сценарий от поиска к вставке внутри класса Phone Это из-за этого массивного задания. Всякий раз, когда мы создаем новую модель, сценарий вставляется. Таким образом, если мы объявим атрибуты безопасными только для сценария поиска, это массовое назначение завершится неудачей. По этой причине мы объявили атрибуты Phone

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

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

Удобные для пользователя URL-адреса всегда хороши

В настоящее время наш URL для просмотра недавно добавленного смартфона использует этот формат:

 http://localhost/gadgetstore/phone/view/[id]

Но как насчет того, чтобы сделать его более привлекательным? Может быть, мы сможем произвести впечатление на наших пользователей, показав им название смартфона в URL? Может быть, что-то вроде http://localhost/gadgetstore/phones/samsung-galaxy-s4

Для реализации URL этого типа просто добавьте следующую строку в правила urlManager в protected/config/main.php

 'phones/<name:[\w\-]+>'=>'phone/show'

Вместе все правила таковы:

 'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName'=>false,
'rules'=>array(
'phones/<name:[\w\-]+>'=>'phone/show', //rule 1
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
),

Что означает правило 1, так это то, что любой URL, начинающийся с ‘phones /’, должен обрабатываться функцией actionShow () класса PhoneController. Кроме того, часть после ‘phones /’ будет передана как параметр запроса GET с именем ‘name’ в actionShow() Делая это, мы можем захватить параметр запроса и использовать его, чтобы найти нужный смартфон по имени!

Функция actionShow()

 public function actionShow(){
  if(isset($_GET['name'])){
    $name=$_GET['name'];
    $name=implode(' ',explode('-',$name));
    $phone=Phone::model()- >find('name=:name',array(':name'=>$name));
    if($phone==null)
    throw new CHttpException(404,'Page Not Found');
     $this->render('view',array('phone'=>$phone));
   }
   else
      throw new CHttpException(404,'Page Not Found');
}

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

Кроме того, обратите внимание, что хотя выбор записей по имени вполне допустим, вы всегда должны выбирать их по уникальным слагам (строки, оптимизированные для URL), на случай, если некоторые записи имеют одинаковое имя. Это делается путем генерирования уникального слагаемого на основе имени в каждой вставке. Например, если Samsung Galaxy S4 был вставлен, слаг может быть samsung-galaxy-s4 Однако, если появится другая модель Samsung Galaxy S4, новый слаг будет что-то вроде samsung-galaxy-s4-01

Кэшируйте ваш контент для лучшей производительности

Реализация кэширования в Yii имеет много типов. В самых простых сценариях мы могли бы выполнить нашу задачу посредством кэширования запросов.

При использовании Active Record мы можем указать, чтобы помещать полученные данные в кеш и впоследствии использовать кеш вместо попадания в базу данных. В нашем приложении кэширование запросов может быть достигнуто с помощью следующего фрагмента:

 $phones=Phone::model()->cache(2000,null,2)->findAll();

Приведенный выше код извлекает данные из БД и добавляет их в кеш. Первый параметр указывает, сколько секунд кэш будет жить. Второй параметр — это зависимость, которая в нашем случае равна нулю. Третий параметр обозначает количество последующих запросов к кешу. Поскольку мы указали 2 в качестве третьего аргумента, следующие 2 запроса будут кэшированы. Итак, в следующие два раза, когда поступит запрос, в кеше будет выполняться поиск контента, а не попадание в базу данных. Это явно повышает производительность, если вы получаете слишком много запросов в секунду.

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

Вывод

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

  • AR Yii предлагает очень хороший API для выбора данных из базы данных различными способами. Вы можете найти данные по атрибутам, первичным ключам и вашим собственным условиям поиска. Просто перейдите по ссылке выше, чтобы узнать больше об этом.

  • Вы должны начать читать о том, как использовать различные шаблоны в ваших правилах URL в файле конфигурации. Это дает вам возможность создавать впечатляющие URL-адреса в ваших приложениях. Помимо этого также полезно создать свой собственный класс правил URL.

  • Кэширование запросов — не единственный механизм кэширования, доступный в Yii. Есть также несколько других реализаций. Документация по Yii содержит отличное руководство по кешированию с помощью Yii.

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