php的db類庫Eloquent單獨使用系列(4)-事件監聽
前面的幾篇文章
本系列文章的目的就是脫離laravel環境使用Eloquent,因為它好用。
本系列文章所有代碼均測試通過。Eloquent版本:5.4.27
本文的目的是使用事件,即鉤子函數,用於保存前後,修改數據模型前後,刪除前後。
下面的代碼假定使用了一個表test2。
主要是4個文件,名字都可以自己改。路徑也可以自己改,只要改namespace即可。
1)User是模型文件,裡面啥都沒有,從我目前測試結果看,也無法在類裡面寫監聽。
2)程序主文件。Ill.php
3)sql日誌事件文件。SqlListener
4)User觀察者類。需被手動註冊到User類上面。
文件層次:
app
- control
- Ill.php
- model
- SqlListener.php
- User.php
- UserObserver.php
模型文件User.php
<?php
namespace appmodel;
use IlluminateDatabaseEloquentModel;
/**
* User模型類
*/
class User extends Model
{
protected $table = "test2";
public $timestamps = false;
// 這是我自己添加的,記錄錯誤信息
private $errinfo="";
public function set_errinfo($info)
{
$this->errinfo = $info;
}
public function get_errinfo
{
return $this->errinfo ;
}
}
觀察者類UserObserver.php
<?php
namespace appmodel;
use appmodelUser;
/**
* User類的觀察者。放置了各種鉤子函數
*
*/
class UserObserver
{
/**
* 添加用戶鉤子
*
* 特別點在於,前置類型的鉤子,如返回假則後面不執行。
* 後綴是ing的鉤子函數,就是前置類型的鉤子。如updating,deleting等。共5個。
*
* @param User $user
* @return void
*/
public function creating(User $user)
{
if ( strlen( $user->user) <2 ) {
$user->set_errinfo("creating: 用戶名至少兩個字元");
return false;
}
}
/**
* 添加用戶鉤子
*
* @param User $user
* @return void
*/
public function created(User $user)
{
echo "<b>in UserObserver.created:". $user->id ."</b><br>";
}
/**
* 修改用戶鉤子
*
* @param User $user
* @return void
*/
public function updated(User $user)
{
echo "<b>in UserObserver.updated:". $user->id ."</b><br>";
}
}
sql日誌文件
<?php
namespace appmodel;
use IlluminateEventsDispatcher;
use IlluminateDatabaseEventsQueryExecuted;
/**
* sql監聽類,記錄sql日誌。
*/
class SqlListener extends Dispatcher
{
/**
* 注意:就改這個函數。也可以記錄到文件日誌里。
*
* @param string|object $event
* @param mixed $payload
* @param bool $halt
* @return array|null
*/
public function dispatch($event, $payload = [], $halt = false)
{
if ($event instanceof QueryExecuted) {
$sql=$event->sql;
if ($event->bindings) {
foreach($event->bindings as $v) {
$sql = preg_replace("/\?/", """. addslashes( $v).""", $sql,1);
}
}
echo "log: ".$sql."<br>";
}
}
}
主程序
<?php
namespace appcontrol;
use IlluminateDatabaseCapsuleManager;
use IlluminateEventsDispatcher;
use appmodelUser;
use appmodelSqlListener;
class Ill
{
/**
* 主程序。
*/
public function hook
{
$capsule = new Manager ;
$capsule->addConnection ( [
"driver" => "mysql",
"host" => "127.0.0.1",
"database" => "test1",
"username" => "root",
"password" => "root",
"charset" => "utf8mb4",
"collation" => "utf8mb4_unicode_ci",
"prefix" => ""
] );
$capsule->setAsGlobal ;
$capsule->bootEloquent ;
// 設置sql日誌監聽
$capsule->setEventDispatcher ( new SqlListener );
// User模型類加鉤子
User::setEventDispatcher ( new Dispatcher );
User::observe ( appmodelUserObserver::class );
// 這句話單純測試log
$users = $capsule::select ( "SELECT * FROM test2 limit 1" );
// 下面幾句測log + 鉤子
$user = new User ;
$user->user = "11";
$result = $user->save ; // 新模型添加
$user->user = "22";
$result = $user->save ; // 已經不是新模型,是已存在模型,所以是修改。
$user = new User ;
$user->user = "3"; // 故意填寫過短的用戶名
$result = $user->save ; // 注意這裡!因為創建模型前置函數creating返回假。
if (! $result) {
echo $user->get_errinfo . "<br>";
}
echo "all ok!";
}
}
下面是瀏覽器輸出結果
log: SELECT * FROM test2 limit 1
log: insert into `test2` (`user`) values ("11")
in UserObserver.created:120
log: update `test2` set `user` = "22" where `id` = "120"
in UserObserver.updated:120
creating: 用戶名至少兩個字元
all ok!
總結:總的來說,還是很好用的。但是,手動註冊觀察者的代碼需要封裝到函數里,在php應用程序的公共起始文件里被調用。
※SpringBoot上傳任意文件功能的實現
※基於vue的顏色選擇器vue-color-picker
※Android與NativeC傳遞數據不正確問題
※ArrayList的實現細節
※Kotlin + Spring Boot 請求參數驗證
TAG:達人科技 |
※apache的commons-email 類庫開發示例
※Django資料庫類庫MySQLdb使用詳解
※Appium 客戶端類庫
※FastText:自然語言處理的利器——一個快速文本表示和分類庫
※C++流類庫繼承體系(IO流,文件流,串流)和 字元串流的基本操作
※沃爾瑪使用更多機器人取代人力,工作包括清理地板、分類庫存等