#### 事件與事件管理器(Events and Events Manager)
Models allow you to implement events that will be thrown when performing an insert/update/delete. They help define business rules for a certain model. The following are the events supported by Phalcon\Mvc\Model and their order of execution:
模型允許您實現在執行插入/更新/刪除時將拋出的事件。它們幫助為特定的模型定義業務規則。以下是Phalcon\Mvc\Model和他們的執行順序所支持的事件:
| Operation 操作 | Name | Can stop operation? 是否停止操作 | Explanation 解釋 |
| --- | --- | --- | --- |
| Inserting/Updating | beforeValidation | YES | Is executed before the fields are validated for not nulls/empty strings or foreign keys 在字段被驗證為非空/空字符串或外鍵之前執行 |
| Inserting | beforeValidationOnCreate | YES | Is executed before the fields are validated for not nulls/empty strings or foreign keys when an insertion operation is being made 在執行插入操作時,在字段被驗證之前執行,而不是空/空字符串或外鍵 |
| Updating | beforeValidationOnUpdate | YES | Is executed before the fields are validated for not nulls/empty strings or foreign keys when an updating operation is being made 在進行更新操作時,在字段被驗證之前執行,而不是空/空字符串或外鍵。 |
| Inserting/Updating | onValidationFails | YES (already stopped) | Is executed after an integrity validator fails 在完整性驗證器失敗后執行 |
| Inserting | afterValidationOnCreate | YES | Is executed after the fields are validated for not nulls/empty strings or foreign keys when an insertion operation is being made 在執行插入操作時,在字段被驗證后執行,而不是空/空字符串或外鍵 |
| Updating | afterValidationOnUpdate | YES | Is executed after the fields are validated for not nulls/empty strings or foreign keys when an updating operation is being made 當一個更新操作被執行時,在字段被驗證為非空/空字符串或外鍵時執行。 |
| Inserting/Updating | afterValidation | YES | Is executed after the fields are validated for not nulls/empty strings or foreign keys 在字段被驗證為非空/空字符串或外鍵后執行 |
| Inserting/Updating | beforeSave | YES | Runs before the required operation over the database system 在數據庫系統上運行之前運行 |
| Updating | beforeUpdate | YES | Runs before the required operation over the database system only when an updating operation is being made 只有當正在進行更新操作時,才需要在數據庫系統上運行所需的操作 |
| Inserting | beforeCreate | YES | Runs before the required operation over the database system only when an inserting operation is being made 只有在進行插入操作時,才需要在數據庫系統上運行所需的操作 |
| Updating | afterUpdate | NO | Runs after the required operation over the database system only when an updating operation is being made 僅當正在進行更新操作時,才需要在數據庫系統上運行所需的操作。 |
| Inserting | afterCreate | NO | Runs after the required operation over the database system only when an inserting operation is being made 只有在進行插入操作時,才需要在數據庫系統上運行所需的操作 |
| Inserting/Updating | afterSave | afterSave | Runs after the required operation over the database system 在數據庫系統上運行所需的操作之后運行 |
#### 模型中自定義事件(Implementing Events in the Model’s class)
The easier way to make a model react to events is implement a method with the same name of the event in the model’s class:
使模型對事件作出反應的更簡單的方法是在模型類中實現一個具有相同名稱的方法:
~~~
<?php
namespace Store\Toys;
use Phalcon\Mvc\Model;
class Robots extends Model
{
public function beforeValidationOnCreate()
{
echo "This is executed before creating a Robot!";
}
}
~~~
Events can be useful to assign values before performing an operation, for example:
在執行操作之前,事件可以很有用地分配值,例如:
~~~
<?php
use Phalcon\Mvc\Model;
class Products extends Model
{
public function beforeCreate()
{
// Set the creation date
$this->created_at = date("Y-m-d H:i:s");
}
public function beforeUpdate()
{
// Set the modification date
$this->modified_in = date("Y-m-d H:i:s");
}
}
~~~
#### 使用自定義事件管理器(Using a custom Events Manager)
Additionally, this component is integrated with Phalcon\Events\Manager, this means we can create listeners that run when an event is triggered.
此外,該組件與事件管理器集成,這意味著我們可以創建在觸發事件時運行的偵聽器。
~~~
<?php
namespace Store\Toys;
use Phalcon\Mvc\Model;
use Phalcon\Events\Event;
use Phalcon\Events\Manager as EventsManager;
class Robots extends Model
{
public function initialize()
{
$eventsManager = new EventsManager();
// Attach an anonymous function as a listener for "model" events
$eventsManager->attach(
"model:beforeSave",
function (Event $event, $robot) {
if ($robot->name === "Scooby Doo") {
echo "Scooby Doo isn't a robot!";
return false;
}
return true;
}
);
// Attach the events manager to the event
$this->setEventsManager($eventsManager);
}
}
~~~
In the example given above, the Events Manager only acts as a bridge between an object and a listener (the anonymous function). Events will be fired to the listener when ‘robots’ are saved:
在上面給出的示例中,事件管理器僅充當對象和偵聽器(匿名函數)之間的橋梁。當“robots”被保存時,事件將被觸發。
~~~
<?php
use Store\Toys\Robots;
$robot = new Robots();
$robot->name = "Scooby Doo";
$robot->year = 1969;
$robot->save();
~~~
If we want all objects created in our application use the same EventsManager, then we need to assign it to the Models Manager:
如果我們想要在我們的應用程序中創建的所有對象使用同一個EventsManager,那么我們需要將它分配給模型管理器:
~~~
<?php
use Phalcon\Events\Event;
use Phalcon\Events\Manager as EventsManager;
// Registering the modelsManager service
$di->setShared(
"modelsManager",
function () {
$eventsManager = new EventsManager();
// Attach an anonymous function as a listener for "model" events
$eventsManager->attach(
"model:beforeSave",
function (Event $event, $model) {
// Catch events produced by the Robots model
if (get_class($model) === "Store\\Toys\\Robots") {
if ($model->name === "Scooby Doo") {
echo "Scooby Doo isn't a robot!";
return false;
}
}
return true;
}
);
// Setting a default EventsManager
$modelsManager = new ModelsManager();
$modelsManager->setEventsManager($eventsManager);
return $modelsManager;
}
);
~~~
If a listener returns false that will stop the operation that is executing currently.
如果偵聽器返回false,將停止當前正在執行的操作。
#### 記錄底層 SQL 語句(Logging Low-Level SQL Statements)
When using high-level abstraction components such as Phalcon\Mvc\Model to access a database, it is difficult to understand which statements are finally sent to the database system. Phalcon\Mvc\Model is supported internally by Phalcon\Db. Phalcon\Logger interacts with Phalcon\Db, providing logging capabilities on the database abstraction layer, thus allowing us to log SQL statements as they happen.
當使用諸如“Phalcon\Mvc\Model”這樣的高級抽象組件來訪問數據庫時,很難理解哪些語句最終被發送到數據庫系統。“Phalcon\Mvc\Model”模式是由“Phalcon\Db”數據庫在內部支持的。在數據庫抽象層上提供Phalcon\Logger記錄功能,從而允許我們記錄SQL語句的發生。
~~~
<?php
use Phalcon\Logger;
use Phalcon\Events\Manager;
use Phalcon\Logger\Adapter\File as FileLogger;
use Phalcon\Db\Adapter\Pdo\Mysql as Connection;
$di->set(
"db",
function () {
$eventsManager = new EventsManager();
$logger = new FileLogger("app/logs/debug.log");
// Listen all the database events
$eventsManager->attach(
"db:beforeQuery",
function ($event, $connection) use ($logger) {
$logger->log(
$connection->getSQLStatement(),
Logger::INFO
);
}
);
$connection = new Connection(
[
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "invo",
]
);
// Assign the eventsManager to the db adapter instance
$connection->setEventsManager($eventsManager);
return $connection;
}
);
~~~
As models access the default database connection, all SQL statements that are sent to the database system will be logged in the file:
當模型訪問默認數據庫連接時,發送到數據庫系統的所有SQL語句都將被記錄在文件中:
~~~
<?php
use Store\Toys\Robots;
$robot = new Robots();
$robot->name = "Robby the Robot";
$robot->created_at = "1956-07-21";
if ($robot->save() === false) {
echo "Cannot save robot";
}
~~~
As above, the file app/logs/db.log will contain something like this:
如上所述,文件app/logs/db.log將包含如下內容:
~~~
[Mon, 30 Apr 12 13:47:18 -0500][DEBUG][Resource Id #77] INSERT INTO robots
(name, created_at) VALUES ('Robby the Robot', '1956-07-21')
~~~
#### 分析 SQL 語句(Profiling SQL Statements)
Thanks to Phalcon\Db, the underlying component of Phalcon\Mvc\Model, it’s possible to profile the SQL statements generated by the ORM in order to analyze the performance of database operations. With this you can diagnose performance problems and to discover bottlenecks.
由于使用了“Phalcon\Db“,Phalcon\Mvc\Model模型的底層組件,可以對ORM生成的SQL語句進行概要分析,從而分析數據庫操作的性能。通過這種方法,您可以診斷性能問題并發現瓶頸。
~~~
<?php
use Phalcon\Db\Profiler as ProfilerDb;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Db\Adapter\Pdo\Mysql as MysqlPdo;
$di->set(
"profiler",
function () {
return new ProfilerDb();
},
true
);
$di->set(
"db",
function () use ($di) {
$eventsManager = new EventsManager();
// Get a shared instance of the DbProfiler
$profiler = $di->getProfiler();
// Listen all the database events
$eventsManager->attach(
"db",
function ($event, $connection) use ($profiler) {
if ($event->getType() === "beforeQuery") {
$profiler->startProfile(
$connection->getSQLStatement()
);
}
if ($event->getType() === "afterQuery") {
$profiler->stopProfile();
}
}
);
$connection = new MysqlPdo(
[
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "invo",
]
);
// Assign the eventsManager to the db adapter instance
$connection->setEventsManager($eventsManager);
return $connection;
}
);
~~~
Profiling some queries:
分析一些查詢:
~~~
<?php
use Store\Toys\Robots;
// Send some SQL statements to the database
Robots::find();
Robots::find(
[
"order" => "name",
]
);
Robots::find(
[
"limit" => 30,
]
);
// Get the generated profiles from the profiler
$profiles = $di->get("profiler")->getProfiles();
foreach ($profiles as $profile) {
echo "SQL Statement: ", $profile->getSQLStatement(), "\n";
echo "Start Time: ", $profile->getInitialTime(), "\n";
echo "Final Time: ", $profile->getFinalTime(), "\n";
echo "Total Elapsed Time: ", $profile->getTotalElapsedSeconds(), "\n";
}
~~~
Each generated profile contains the duration in milliseconds that each instruction takes to complete as well as the generated SQL statement.
每個生成的概要文件包含了每條指令完成的時間和生成的SQL語句的持續時間。
- Welcome
- 安裝
- XAMPP 下的安裝
- WAMP 下安裝
- Apache 安裝說明
- Nginx 安裝說明
- Cherokee 安裝說明
- 使用 PHP 內置 web 服務器
- Phalcon 開發工具
- Windows 系統下使用 Phalcon 開發工具
- Mac OS X 系統下使用 Phalcon 開發工具
- Linux 系統下使用 Phalcon 開發工具
- 教程 1:讓我們通過例子來學習
- 教程 2:INVO簡介
- 教程 3: 保護INVO
- 教程4: 使用CRUD
- 教程5: 定制INVO
- 教程6: V?kuró
- 教程 7:創建簡單的 REST API
- 依賴注入與服務定位器(Dependency Injection/Service Location)
- MVC 架構(The MVC Architecture)
- 使用控制器(Using Controllers)
- 使用模型(Working with Models)
- 模型關系(Model Relationships)
- 模型事件(Model Events)
- 模型行為(Model Behaviors)
- 模型元數據(Models Metadata)
- 事務管理(Model Transactions)
- 模型驗證(Validating Models)
- Working with Models (Advanced)
- Phalcon 查詢語言(Phalcon Query Language (PHQL))
- 緩存對象關系映射(Caching in the ORM)
- 對象文檔映射 ODM (Object-Document Mapper)
- 使用視圖(Using Views)
- 視圖助手 (Tags)(View Helpers (Tags))