Статьи

Как программировать с Yii2: изучение MVC, форм и макетов

Конечный продукт
Что вы будете создавать

В разделе «Программирование с Yii2: начало работы» мы настроили Yii2 локально, создали приложение Hello World, настроили удаленный сервер и использовали Github для развертывания нашего кода. В этом руководстве будут рассмотрены некоторые из основных концепций Yii, связанных с реализацией инфраструктуры MVC: модели, представления и контроллеры. Мы также рассмотрим макеты и настройку навигационных меню и элементов Bootstrap.

Для этих примеров мы представим, что мы создаем структуру для публикации простых обновлений статуса, например, наш собственный мини-Twitter. Однако мы не будем заходить так далеко, чтобы хранить данные в базе данных. Я сохраню это для следующего урока, в котором будет рассмотрена возможность создания леса в Yii, под названием Gii.

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

Какая модель? Википедия говорит : « Модель уведомляет связанные представления и контроллеры, когда в ее состоянии произошли изменения. Это уведомление позволяет представлениям производить обновленный вывод, а контроллеры — изменять доступный набор команд».

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

Лучшая практика заключается в том, чтобы встроить в свои модели как можно больше функциональности и интеллекта. В практике MVC вы строите модели «тяжелые» и контроллеры, а представления легкие. Yii предоставляет некоторые превосходные функции, специфичные для тех видов деятельности, которые вы делаете в веб-разработке и разработке приложений, которые упрощают построение моделей, особенно когда речь идет о формах и базах данных; Большую часть этого мы рассмотрим в следующих уроках.

Давайте создадим нашу модель статуса. Для наших примеров кодирования вы можете использовать репозиторий Git. Я основываюсь на том, что мы создали в учебном пособии « Приступая к работе» — я пометил его здесь для справки. Github репозиторий для готового урока находится здесь .

Мы создадим Status.php в /hello/models/Status.php . Чтобы опубликовать статусное сообщение, нам нужно собрать текст сообщения от пользователя. Мы также создадим поле разрешений для публичной или частной публикации.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
 
namespace app\models;
 
use yii\base\Model;
 
class Status extends Model
{
    const PERMISSIONS_PRIVATE = 10;
    const PERMISSIONS_PUBLIC = 20;
     
    public $text;
    public $permissions;
 
    public function rules()
    {
        return [
            [[‘text’,’permissions’], ‘required’],
        ];
    }
     
    public function getPermissions() {
      return array (self::PERMISSIONS_PRIVATE=>’Private’,self::PERMISSIONS_PUBLIC=>’Public’);
    }
     
    public function getPermissionsLabel($permissions) {
      if ($permissions==self::PERMISSIONS_PUBLIC) {
        return ‘Public’;
      } else {
        return ‘Private’;
      }
    }
}
?>

Обратите внимание на функцию правил — она ​​используется при проверке формы в Yii, чтобы гарантировать, что пользователи вводят соответствующую информацию в каждое поле. Yii использует JavaScript для проверки форм в качестве пользовательских типов.

Созданная getPermissions() функция getPermissions() будет использоваться для элементов раскрывающегося списка формы.

Теперь давайте перейдем к созданию контроллера, позволяющего пользователю создавать и просматривать текстовые обновления.

Что за контроллер? Википедия говорит : « Контроллер может отправлять команды модели для обновления состояния модели (например, редактирование документа). Он также может отправлять команды в связанный вид для изменения представления представления модели». В типичном веб-приложении Yii URL-путь к странице вызывает контроллер для загрузки данных для страницы с использованием модели и визуализации страницы с использованием представления.

Лучше всего логически группировать связанные функции в одном контроллере. Различные методы контроллера, называемые действиями, реализуют каждую функцию. Они часто соответствуют определенным страницам. Например, http: // localhost: 8888 / hello / web / status / create вызовет действие создания StatusController, которое мы собираемся построить.

При разработке функций, связанных с Status, вы должны сгруппировать эти функции в один StatusController.php. Сейчас мы просто создадим функцию создания.

В /hello/controllers/ создайте StatusController.php:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
 
namespace app\controllers;
 
use Yii;
use yii\web\Controller;
use app\models\Status;
 
class StatusController extends Controller
{
    public function actionCreate()
    {
        $model = new Status;
 
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            // valid data received in $model
            return $this->render(‘view’, [‘model’ => $model]);
        } else {
            // either the page is initially displayed or there is some validation error
            return $this->render(‘create’, [‘model’ => $model]);
        }
    }
}
?>

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

Какой вид? Википедия говорит : «Представление запрашивает информацию из модели, которую оно использует для создания выходного представления для пользователя». В Yii представление использует PHP-подобный язык шаблонов для визуализации вывода страницы в HTML, используя данные, загруженные моделью и доставленные из контроллера.

Представления обычно расположены в одной папке, связанной со связанным контроллером, например, представления StatusController находятся в папке views/status .

В Yii код формы обычно включается в то, что называется частичным представлением. Эти файлы часто имеют префикс подчеркивания. Они предназначены для включения другими взглядами. Это позволяет повторно использовать действительный код формы на страницах создания и обновления.

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

Вот простой пример нашего /hello/views/status.view.php файла представления для отображения опубликованных данных:

01
02
03
04
05
06
07
08
09
10
11
12
<?php
  use yii\helpers\Html;
?>
 
<h1>Your Status Update</strong></h1>
<p><label>Text</label>:</p>
  <?= Html::encode($model->text) ?>
<br /><br />
<p><label>Permissions</label>:</p>
<?php
echo $model->getPermissionsLabel($model->permissions);
?>

Обратите внимание, что файл представления представляет собой смесь HTML и PHP. Когда контроллер получает опубликованные данные, он отображает вышеуказанное представление, показывающее, какие данные предоставил пользователь.

Но теперь давайте поговорим о формах и создадим файл представления формы create.

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

Yii2 ActiveForm Blank

Вот пример формы для создания обновления статуса:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?php
  use yii\helpers\Html;
  use yii\widgets\ActiveForm;
  use app\models\Status;
?>
<?php $form = ActiveForm::begin();?>
    <?= $form->field($model, ‘text’)->textArea([‘rows’ => ‘4’])->label(‘Status Update’);
 
    <?=
    $form->field($model, ‘permissions’)->dropDownList($model->getPermissions(),
             [‘prompt’=>’- Choose Your Permissions -‘]) ?>
 
    <div class=»form-group»>
        <?= Html::submitButton(‘Submit’, [‘class’ => ‘btn btn-primary’]) ?>
    </div>
 
<?php ActiveForm::end();

Виджет Yii2 ActiveForm используется для генерации HTML для наших полей ввода. Обратите внимание, как раскрывающийся список вызывает метод getPermissions модели getPermissions .

Yii2 ActiveForm Создать

Нажатие на кнопку «Отправить» возвращает к действию создания StatusController. Когда полученные данные получены, они отображают файл view.php вместо файла формы create.php.

Вот как выглядит файл представления при визуализации с помощью view.php:

Yii2 Status View

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

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

Если вы посмотрите на \hello\views\layouts\main.php , вы увидите структуру внешнего макета:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?php
use yii\helpers\Html;
use yii\bootstrap\Nav;
use yii\bootstrap\NavBar;
use yii\widgets\Breadcrumbs;
use app\assets\AppAsset;
 
/* @var $this \yii\web\View */
/* @var $content string */
 
AppAsset::register($this);
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang=»<?= Yii::$app->language ?>»>
<head>
    <meta charset=»<?= Yii::$app->charset ?>»/>
    <meta name=»viewport» content=»width=device-width, initial-scale=1″>
    <?= Html::csrfMetaTags() ?>
    <title><?= Html::encode($this->title) ?></title>
    <?php $this->head() ?>
</head>
<body>
 
<?php $this->beginBody() ?>
    <div class=»wrap»>
        <?php
            NavBar::begin([
                ‘brandLabel’ => ‘My Company’,
                ‘brandUrl’ => Yii::$app->homeUrl,
                ‘options’ => [
                    ‘class’ => ‘navbar-inverse navbar-fixed-top’,
                ],
            ]);
            echo Nav::widget([
                ‘options’ => [‘class’ => ‘navbar-nav navbar-right’],
                ‘items’ => [
                    [‘label’ => ‘Home’, ‘url’ => [‘/site/index’]],
                    [‘label’ => ‘About’, ‘url’ => [‘/site/about’]],
                    [‘label’ => ‘Contact’, ‘url’ => [‘/site/contact’]],
                    Yii::$app->user->isGuest ?
                        [‘label’ => ‘Login’, ‘url’ => [‘/site/login’]] :
                        [‘label’ => ‘Logout (‘ . Yii::$app->user->identity->username . ‘)’,
                            ‘url’ => [‘/site/logout’],
                            ‘linkOptions’ => [‘data-method’ => ‘post’]],
                ],
            ]);
            NavBar::end();
        ?>
 
        <div class=»container»>
            <?= Breadcrumbs::widget([
                ‘links’ => isset($this->params[‘breadcrumbs’]) ?
            ]) ?>
            <?= $content ?>
        </div>
    </div>
 
    <footer class=»footer»>
        <div class=»container»>
            <p class=»pull-left»>&copy;
            <p class=»pull-right»><?= Yii::powered() ?></p>
        </div>
    </footer>
 
<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>

Представления в основном представляют внутренние страницы веб-сайта — что находится между заголовком и панелью навигации и началом нижнего колонтитула. Они отображаются, когда макет отображает $content :

1
2
3
4
5
6
<div class=»container»>
           <?= Breadcrumbs::widget([
               ‘links’ => isset($this->params[‘breadcrumbs’]) ?
           ]) ?>
           <?= $content ?>
       </div>

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

Теперь давайте обновим панель навигации, добавив в нее меню «Состояние» с действием «создать». Поскольку Yii2 использует Bootstrap для своих макетов и стилей, нам просто нужно сказать ему создать выпадающий список Bootstrap.

Обновите Nav::widget чтобы иметь вложенный массив:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
echo Nav::widget([
               ‘options’ => [‘class’ => ‘navbar-nav navbar-right’],
               ‘items’ => [
                   [‘label’ => ‘Home’, ‘url’ => [‘/site/index’]],
                   [
                      ‘label’ => ‘Status’,
                      ‘items’ => [
                           [‘label’ => ‘Create’, ‘url’ => [‘/status/create’]],
                       ],
                   ],
                   [‘label’ => ‘About’, ‘url’ => [‘/site/about’]],
                   [‘label’ => ‘Contact’, ‘url’ => [‘/site/contact’]],
                   Yii::$app->user->isGuest ?
                       [‘label’ => ‘Login’, ‘url’ => [‘/site/login’]] :
                       [‘label’ => ‘Logout (‘ . Yii::$app->user->identity->username . ‘)’,
                           ‘url’ => [‘/site/logout’],
                           ‘linkOptions’ => [‘data-method’ => ‘post’]],
               ],
           ]);

Вот что вы должны увидеть:

Yii2 NavBar и выпадающее меню

Теперь, когда вы немного узнали о том, как архитектура MVC Yii работает на практике, включая модели, представления, контроллеры, формы и макеты, мы создадим схему базы данных для состояний и будем использовать генератор скаффолдинга Yii, Gii, для автоматического создания всего этого для нас. Вещи начнут двигаться немного быстрее.

Если вы хотите узнать, когда появится следующий учебник по Yii2, следуйте за мной @reifman в Твиттере или зайдите на страницу инструктора Tuts + . Моя страница инструктора будет включать все статьи из этой серии, как только они будут опубликованы.