Если вы спрашиваете: «Что такое Yii?» Посмотрите мой предыдущий учебник: Введение в Yii Framework , который рассматривает преимущества Yii и включает обзор того, что нового в Yii 2.0, выпущенном в октябре 2014 года.
В этой серии «Программирование с Yii2» я расскажу читателям, как использовать обновленную версию Yii2 Framework для PHP. В этом руководстве мы рассмотрим поведение временных меток, которое сокращает объем кода, который необходимо писать для каждой новой модели, для общей операции создания временных меток для вставок и обновлений. Мы также погрузимся в исходный код Yii2, исследуя, как реализовано поведение.
Для примеров из этого руководства мы продолжим представлять, что создаем основу для публикации простых обновлений статуса, например, нашего собственного мини-Twitter.
Просто напоминание, я участвую в комментариях ниже. Мне особенно интересно, если у вас есть другие подходы, дополнительные идеи или вы хотите предложить темы для будущих уроков.
Что такое поведение?
Yii2 Поведения по сути являются миксинами . Википедия описывает миксины как «класс, который содержит комбинацию методов из других классов. То, как такая комбинация выполняется, зависит от языка, но не от наследования».
Yii описывает их так:
Присоединение поведения к компоненту «внедряет» методы и свойства поведения в компонент, делая эти методы и свойства доступными, как если бы они были определены в самом классе компонента.
Yii2 предлагает несколько встроенных поведений, большинство из которых мы будем документировать, включая медлительные , обвиняемые и временные метки. Поведения — это простой способ повторного использования общего кода во многих ваших моделях данных без необходимости повторять код во многих местах. Внедрение поведения в модель часто может быть сделано всего двумя строками кода. По мере увеличения количества моделей в вашем приложении поведение становится все более полезным.
Каково поведение метки времени?
Поведение Timestamp позволяет нам легко реализовать часто необходимую задачу назначения текущей даты и времени для вставок и обновлений в модели ActiveRecord, автоматически устанавливая свойства для created_at
и updated_at
.
Ранее в этой серии мы реализовали временную метку вручную. Всякий раз, когда модели состояния были опубликованы пользователем, отправляющим форму, мы назначали текущую временную метку Unix обоим полям:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public function actionCreate()
{
$model = new Status();
if ($model->load(Yii::$app->request->post())) {
$model->created_at = time();
$model->updated_at = time();
if ($model->save()) {
return $this->redirect([‘view’, ‘id’ => $model->id]);
} else {
var_dump ($model->getErrors());
}
}
|
Реализация поведения Timestamp сделает это автоматически для нас и может быть легко добавлена ко всем моделям ActiveRecord в веб-приложении.
Реализация поведения метки времени в модели состояния
Почти у каждой модели, которую я создаю в Yii, есть поля created_at
и updated_at
. Это хорошая практика. Таким образом, поведение Timestamp полезно практически в каждой модели.
Добавление поведения метки времени в модель состояния
В models/Status.php
мы добавляем TimestampBehavior
после Sluggable
и Blameable
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public function behaviors()
{
return [
[
‘class’ => SluggableBehavior::className(),
‘attribute’ => ‘message’,
‘immutable’ => true,
‘ensureUnique’=>true,
],
[
‘class’ => BlameableBehavior::className(),
‘createdByAttribute’ => ‘created_by’,
‘updatedByAttribute’ => ‘updated_by’,
],
‘timestamp’ => [
‘class’ => ‘yii\behaviors\TimestampBehavior’,
‘attributes’ => [
ActiveRecord::EVENT_BEFORE_INSERT => [‘created_at’, ‘updated_at’],
ActiveRecord::EVENT_BEFORE_UPDATE => [‘updated_at’],
],
],
];
}
|
Мы также должны включить класс ActiveRecord в начало нашей модели (я всегда забываю эту часть):
1
2
3
4
5
6
7
8
|
<?php
namespace app\models;
use Yii;
use yii\db\ActiveRecord;
use yii\behaviors\SluggableBehavior;
use yii\behaviors\BlameableBehavior;
|
Затем мы удаляем обязательное правило для created_at
и updated_at
в правилах модели:
1
2
3
4
5
6
7
8
|
public function rules()
{
return [
[[‘message’, ‘created_at’, ‘updated_at’], ‘required’],
[[‘message’], ‘string’],
[[‘permissions’, ‘created_at’, ‘updated_at’,’created_by’], ‘integer’]
];
}
|
Как это:
1
2
3
4
5
6
7
8
|
public function rules()
{
return [
[[‘message’], ‘required’],
[[‘message’], ‘string’],
[[‘permissions’, ‘created_at’, ‘updated_at’,’created_by’], ‘integer’]
];
}
|
Это позволяет валидации пройти успешно и перейти к поведению.
Нам также необходимо удалить назначения StatusController create_at и updated_at
в действии create:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
public function actionCreate()
{
$model = new Status();
if ($model->load(Yii::$app->request->post())) {
if ($model->save()) {
return $this->redirect([‘view’, ‘id’ => $model->id]);
} else {
var_dump ($model->getErrors());
}
}
return $this->render(‘create’, [
‘model’ => $model,
]);
}
|
Как только все эти изменения будут завершены, мы можем написать новую запись статуса:
И результирующее представление показывает настройки созданного и updated_at
, сделанные поведением Timestamp.
Сенсорный метод
Поведение Timestamp также предоставляет метод с именем touch()
который позволяет назначать текущую метку времени указанным атрибутам и сохранять их в базе данных.
1
|
$model->touch(‘updated_at’);
|
Например, если у вас есть фоновое задание cron, которое выполняет некоторую обработку таблицы состояния, у вас может быть last_processed_at
времени last_processed_at
которой вы прикрепляете поведение. Каждый раз, когда запускается задание cron, вы должны коснуться этого поля
1
|
$model->touch(‘last_processed_at’);
|
Поведение метки времени Исходный код
Поскольку Yii2 теперь поддерживает соглашения об именах PSR-4 , проще погрузиться в код инфраструктуры, чтобы увидеть, как он работает. Давайте посмотрим на код TimestampBehavior
чтобы понять, как он реализован.
Код связан с GitHub со страницы документации :
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
|
class TimestampBehavior extends AttributeBehavior
{
/**
* @var string the attribute that will receive timestamp value
* Set this property to false if you do not want to record the creation time.
*/
public $createdAtAttribute = ‘created_at’;
/**
* @var string the attribute that will receive timestamp value.
* Set this property to false if you do not want to record the update time.
*/
public $updatedAtAttribute = ‘updated_at’;
/**
* @var callable|Expression The expression that will be used for generating the timestamp.
* This can be either an anonymous function that returns the timestamp value,
* or an [[Expression]] object representing a DB expression (eg `new Expression(‘NOW()’)`).
* If not set, it will use the value of `time()` to set the attributes.
*/
public $value;
/**
* @inheritdoc
*/
public function init()
{
parent::init();
if (empty($this->attributes)) {
$this->attributes = [
BaseActiveRecord::EVENT_BEFORE_INSERT => [$this->createdAtAttribute, $this->updatedAtAttribute],
BaseActiveRecord::EVENT_BEFORE_UPDATE => $this->updatedAtAttribute,
];
}
}
/**
* @inheritdoc
*/
protected function getValue($event)
{
if ($this->value instanceof Expression) {
return $this->value;
} else {
return $this->value !== null ?
}
}
/**
* Updates a timestamp attribute to the current timestamp.
*
* «`php
* $model->touch(‘lastVisit’);
* «`
* @param string $attribute the name of the attribute to update.
*/
public function touch($attribute)
{
$this->owner->updateAttributes(array_fill_keys((array) $attribute, $this->getValue(null)));
}
}
|
Атрибуты по умолчанию определены здесь, и они могут быть настроены в наших моделях:
1
2
|
public $createdAtAttribute = ‘created_at’;
public $updatedAtAttribute = ‘updated_at’;
|
При инициализации поведение определяет, какие события вызывают обновления меток времени для указанных атрибутов:
01
02
03
04
05
06
07
08
09
10
|
public function init()
{
parent::init();
if (empty($this->attributes)) {
$this->attributes = [
BaseActiveRecord::EVENT_BEFORE_INSERT => [$this->createdAtAttribute, $this->updatedAtAttribute],
BaseActiveRecord::EVENT_BEFORE_UPDATE => $this->updatedAtAttribute,
];
}
}
|
Вы можете прочитать больше о событиях Yii2 ActiveRecord здесь .
Метод getValue
возвращает текущую метку времени для атрибута, если он не определен:
1
2
3
4
5
6
7
8
|
protected function getValue($event)
{
if ($this->value instanceof Expression) {
return $this->value;
} else {
return $this->value !== null ?
}
}
|
По умолчанию TimestampBehavior
будет заполнять атрибуты created_at
и updated_at
текущей отметкой времени при вставке связанного объекта. Он будет заполнять атрибут updated_at
отметкой времени при обновлении объекта. Если пользовательская функция не назначена, она использует функцию PHP time()
, которая возвращает текущую временную метку Unix.
Он также реализует touch
метод для определенных атрибутов:
01
02
03
04
05
06
07
08
09
10
11
12
|
/**
* Updates a timestamp attribute to the current timestamp.
*
* «`php
* $model->touch(‘lastVisit’);
* «`
* @param string $attribute the name of the attribute to update.
*/
public function touch($attribute)
{
$this->owner->updateAttributes(array_fill_keys((array) $attribute, $this->getValue(null)));
}
|
Надеюсь, это даст вам представление о том, как реализовать собственную модель поведения. Если вы создадите что-то новое, опубликуйте ссылку на код в комментариях, чтобы другие могли это проверить.
Что дальше?
Надеюсь, вам понравилось изучать поведение меток времени Yii2 и изучать исходный код Yii2.
Следите за будущими уроками в моей серии «Программирование с Yii2», поскольку я продолжаю изучать различные аспекты фреймворка. Вы также можете проверить мою серию «Построение стартапа с помощью PHP» , которая использует расширенный шаблон Yii2, когда я создаю реальное приложение.
Я приветствую тематические и тематические запросы. Вы можете опубликовать их в комментариях ниже или написать мне по электронной почте на моем сайте Lookahead Consulting .
Если вы хотите узнать, когда появится следующий учебник по Yii2, следуйте за мной @reifman в Твиттере или зайдите на страницу моего инструктора . Моя страница инструктора будет включать все статьи из этой серии, как только они будут опубликованы.
Ссылки по теме
- Полное руководство по Yii2: поведение
- Документация Yii2: поведение метки времени
- Yii2 Developer Exchange , мой ресурсный сайт Yii2