Поведение моделей
Поведение — это общее поведение, которое могут принять несколько моделей для повторного использования кода; ORM предоставляет API для реализации поведения в ваших моделях. Также вы можете использовать события и обратные вызовы, как показано ранее, в качестве альтернативы для реализации поведения с большей свободой.
Поведение должно быть добавлено в инициализатор модели; модель может иметь ноль или более поведений:
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Behavior\Timestampable;
class Users extends Model
{
public $id;
public $name;
public $created_at;
public function initialize()
{
$this->addBehavior(
new Timestampable(
[
"beforeCreate" => [
"field" => "created_at",
"format" => "Y-m-d",
]
]
)
);
}
}
Следующие встроенные поведения предоставляются фреймворком:
| Имя | Описание |
|---|---|
| Timestampable | Позволяет автоматически обновлять атрибут модели, сохраняя дату и время создания или обновления записи |
| SoftDelete | Вместо постоянного удаления записи она помечает запись как удалённую, изменяя значение столбца флага |
Timestampable
Это поведение принимает массив параметров; ключ первого уровня должен быть именем события, указывающим, когда столбец должен быть назначен:
use Phalcon\Mvc\Model\Behavior\Timestampable;
public function initialize()
{
$this->addBehavior(
new Timestampable(
[
"beforeCreate" => [
"field" => "created_at",
"format" => "Y-m-d",
]
]
)
);
}
Каждое событие может иметь свои собственные параметры; «поле» — это имя столбца, который должен быть обновлён; если «формат» — это строка, она будет использоваться в качестве формата функции PHP date; формат также может быть анонимной функцией, предоставляя вам свободу для генерации любого типа отметки времени:
use DateTime;
use DateTimeZone;
use Phalcon\Mvc\Model\Behavior\Timestampable;
public function initialize()
{
$this->addBehavior(
new Timestampable(
[
"beforeCreate" => [
"field" => "created_at",
"format" => function () {
$datetime = new Datetime(
new DateTimeZone("Europe/Stockholm")
);
return $datetime->format("Y-m-d H:i:sP");
}
]
]
)
);
}
Если параметр «формат» опущен, будет использоваться отметка времени, используя функцию PHP time.
SoftDelete
Это поведение можно использовать следующим образом:
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Behavior\SoftDelete;
class Users extends Model
{
const DELETED = "D";
const NOT_DELETED = "N";
public $id;
public $name;
public $status;
public function initialize()
{
$this->addBehavior(
new SoftDelete(
[
"field" => "status",
"value" => Users::DELETED,
]
)
);
}
}
Это поведение принимает два параметра: «поле» и «значение»; «поле» определяет, какой столбец необходимо обновить, а «значение» — значение для удаления. Предположим, что таблица «users» имеет следующие данные:
mysql> select * from users; +----+---------+--------+ | id | name | status | +----+---------+--------+ | 1 | Lana | N | | 2 | Brandon | N | +----+---------+--------+ 2 rows in set (0.00 sec)
Если мы удаляем любую из двух записей, статус будет обновлен, вместо удаления записи:
Users::findFirst(2)->delete();
Результат операции будет следующими данными в таблице:
mysql> select * from users; +----+---------+--------+ | id | name | status | +----+---------+--------+ | 1 | Lana | N | | 2 | Brandon | D | +----+---------+--------+ 2 rows in set (0.01 sec)
Обратите внимание, что вам необходимо указать условие удаления в ваших запросах, чтобы эффективно игнорировать их как удалённые записи; это поведение этого не поддерживает.
Создание собственных поведений
ORM предоставляет API для создания собственных поведений. Поведение должно быть классом, реализующим Phalcon\Mvc\Model\BehaviorInterface. Кроме того, Phalcon\Mvc\Model\Behavior предоставляет большинство необходимых методов для облегчения реализации поведения.
Следующее поведение — пример, оно реализует поведение Blameable, которое помогает определить пользователя, который выполняет операции над моделью:
use Phalcon\Mvc\Model\Behavior;
use Phalcon\Mvc\Model\BehaviorInterface;
class Blameable extends Behavior implements BehaviorInterface
{
public function notify($eventType, $model)
{
switch ($eventType) {
case "afterCreate":
case "afterDelete":
case "afterUpdate":
$userName = // ... get the current user from session
// Store in a log the username, event type and primary key
file_put_contents(
"logs/blamable-log.txt",
$userName . " " . $eventType . " " . $model->id
);
break;
default:
/* ignore the rest of events */
}
}
}
Предыдущее — очень простое поведение, но оно иллюстрирует, как создать поведение. Теперь добавим это поведение к модели:
use Phalcon\Mvc\Model;
class Profiles extends Model
{
public function initialize()
{
$this->addBehavior(
new Blameable()
);
}
}
Поведение также способно перехватывать отсутствующие методы в ваших моделях:
use Phalcon\Tag;
use Phalcon\Mvc\Model\Behavior;
use Phalcon\Mvc\Model\BehaviorInterface;
class Sluggable extends Behavior implements BehaviorInterface
{
public function missingMethod($model, $method, $arguments = [])
{
// If the method is 'getSlug' convert the title
if ($method === "getSlug") {
return Tag::friendlyTitle($model->title);
}
}
}
Вызов этого метода в модели, которая реализует Sluggable, возвращает SEO-оптимизированное название:
$title = $post->getSlug();
Использование Traits в качестве поведений
Начиная с PHP 5.4, вы можете использовать Traits для повторного использования кода в ваших классах; это ещё один способ реализации пользовательских поведений. Следующий трейт реализует простую версию поведения Timestampable:
trait MyTimestampable
{
public function beforeCreate()
{
$this->created_at = date("r");
}
public function beforeUpdate()
{
$this->updated_at = date("r");
}
}
Затем вы можете использовать его в своей модели следующим образом:
use Phalcon\Mvc\Model;
class Products extends Model
{
use MyTimestampable;
}
© 2011–2017 Phalcon Framework Team
Licensed under the Creative Commons Attribution License 3.0.
https://docs.phalconphp.com/en/latest/reference/model-behaviors.html