需求 打印出swoft的所有sql日志到控制台或者文件
只要打开listener 下面 Dbranlisten.php 里面最后一行注释即可,swoft已经帮我们实现好了
____ _____ ___ ___
/ __/ _____ / _/ /_ |_ | / _ \
_\ \| |/|/ / _ \/ _/ __/ / __/_/ // /
/___/|__,__/\___/_/ \__/ /____(_)___/
SERVER INFORMATION(v2.0.9)
********************************************************************************
* HTTP | Listen: 0.0.0.0:18306, Mode: Process, Worker: 6, Task worker: 12
********************************************************************************
HTTP Server Start Success!
2020/07/17-20:55:29 [INFO] Swoft\Server\Server:startSwoole(491) Swoole\Runtime::enableCoroutine
2020/07/17-20:55:29 [INFO] Swoft\Listener\BeforeStartListener:handle(27) Server extra info: pidFile @runtime/swoft.pid
2020/07/17-20:55:29 [INFO] Swoft\Listener\BeforeStartListener:handle(28) Registered swoole events:
start, shutdown, managerStart, managerStop, workerStart, workerStop, workerError, request, task, finish
Server start success (Master PID: 17681, Manager PID: 17686)
[INFO] insert into `tb_users` (`name`, `age`, `created_at`) values ('test', 10, '2020-07-17 20:55:50')
为什么会监听到日志 事件什么时候触发的
/**
* Class RanListener
*
* @since 2.0
*
* @Listener(DbEvent::SQL_RAN)
*/
/**
* Sql ran after
*/
public const SQL_RAN = 'swoft.db.ran';
全项目搜索 DbEvent::SQL_RAN 发现除了调用的地方 还有写入的地方
Connection.php
/**
* Run a SQL statement and log its execution context.
*
* @param string $query
* @param array $bindings
* @param Closure $callback
*
* @return mixed
*
* @throws DbException
*/
protected function run(string $query, array $bindings, Closure $callback)
{
$this->reconnectIfMissingConnection();
$start = microtime(true);
// Here we will run this query. If an exception occurs we'll determine if it was
// caused by a connection that has been lost. If that is the cause, we'll try
$result = $this->runQueryCallback($query, $bindings, $callback);
$time = $this->getElapsedTime($start);
$this->fireEvent(DbEvent::SQL_RAN, $query, $bindings, $time);
// Once we have run the query we will calculate the time that it took to run and
// then log the query, bindings, and execution time so we will report them on
// the event that the developer needs them. We'll log time in milliseconds.
return $result;
}
这个方法 $this->fireEvent(DbEvent::SQL_RAN, $query, $bindings, $time);
往下
HasEvent.php
/**
* Fire the given event for the model.
*
* @param string $event
* @param mixed ...$args
*
* @return bool
*/
protected function fireEvent(string $event, ...$args): bool
{
// Trigger method public event
$eventPublicResult = Swoft::trigger($event, $this, ...$args);
if ($eventPublicResult->isPropagationStopped() === true) {
return false;
}
// Not model no trigger
if ($this->getContextName() !== 'model') {
return true;
}
// Trigger model method event
$modelEventResult = Swoft::trigger($this->getModelEventName($event), $this, ...$args);
if ($modelEventResult->isPropagationStopped() === true) {
return false;
}
return true;
}
发现 Swoft::trigger($event, $this, ...$args);
往下 Swoft.php
/**
* Trigger an swoft application event
*
* @param string|EventInterface $event eg: 'app.start' 'app.stop'
* @param null|mixed $target
* @param array $params
*
* @return EventInterface
*/
public static function trigger($event, $target = null, ...$params): EventInterface
{
/** @see EventManager::trigger() */
return BeanFactory::getSingleton('eventManager')->trigger($event, $target, $params);
}
EventManage.php
/**
* Trigger an event. Can accept an EventInterface or will create one if not passed
*
* @param string|EventInterface $event 'app.start' 'app.stop'
* @param mixed|string $target It is object or string.
* @param array|mixed $args
*
* @return EventInterface
* @throws InvalidArgumentException
*/
public function trigger($event, $target = null, array $args = []): EventInterface
{
if ($isString = is_string($event)) {
$name = trim($event);
} elseif ($event instanceof EventInterface) {
$name = trim($event->getName());
} else {
throw new InvalidArgumentException('Invalid event params for trigger event handler');
}
$shouldCall = [];
// Have matched listener
if (isset($this->listenedEvents[$name])) {
$shouldCall[$name] = '';
}
// Like 'app.db.query' => prefix: 'app.db'
if ($pos = strrpos($name, '.')) {
$prefix = substr($name, 0, $pos);
// Have a wildcards listener. eg 'app.db.*'
$wildcardEvent = $prefix . '.*';
if (isset($this->listenedEvents[$wildcardEvent])) {
$shouldCall[$wildcardEvent] = substr($name, $pos + 1);
}
}
// Not found listeners
if (!$shouldCall) {
return $isString ? $this->basicEvent : $event;
}
/** @var EventInterface $event */
if ($isString) {
$event = $this->events[$name] ?? $this->basicEvent;
}
// Initial value
$event->setName($name);
$event->setParams($args);
$event->setTarget($target);
$event->stopPropagation(false);
// Notify event listeners
foreach ($shouldCall as $name => $method) {
$this->triggerListeners($this->listeners[$name], $event, $method);
if ($event->isPropagationStopped()) {
return $this->destroyAfterFire ? $event->destroy() : $event;
}
}
// Have global wildcards '*' listener.
if (isset($this->listenedEvents['*'])) {
$this->triggerListeners($this->listeners['*'], $event);
}
return $this->destroyAfterFire ? $event->destroy() : $event;
}
调用 triggerListeners
/**
* @param array|ListenerQueue $listeners
* @param EventInterface $event
* @param string $method
*/
protected function triggerListeners($listeners, EventInterface $event, string $method = ''): void
{
// $handled = false;
$name = $event->getName();
$callable = false === strpos($name, '.');
// 循环调用监听器,处理事件
foreach ($listeners as $listener) {
if ($event->isPropagationStopped()) {
break;
}
if (is_object($listener)) {
if ($listener instanceof EventHandlerInterface) {
$listener->handle($event);
} elseif ($method && method_exists($listener, $method)) {
$listener->$method($event);
} elseif ($callable && method_exists($listener, $name)) {
$listener->$name($event);
} elseif (method_exists($listener, '__invoke')) {
$listener($event);
}
} elseif (is_callable($listener)) {
$listener($event);
}
}
}
最终调用监听的 hadle方法
所以是 调动trigger 就会触发匹配到的监听,执行监听的hanle方法
模仿 自己触发event 自己listen
控制器 HomeController 里面新建方法
/**
* @RequestMapping("/add")
*/
public function add()
{
// $user = new Users();
// $user->fill(['name'=>'test','age'=>10])->save();
// return $user;
Swoft::trigger("swoft.wang","this is message",'hello','world');
}
app\Listener\Test\WangListener.php
<?php declare(strict_types=1);
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @document https://swoft.org/docs
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/
namespace App\Listener\Test;
use Swoft\Event\Annotation\Mapping\Listener;
use Swoft\Event\EventHandlerInterface;
use Swoft\Event\EventInterface;
use Swoft\Exception\SwoftException;
use Swoft\Log\Helper\CLog;
use Swoft\Server\SwooleEvent;
/**
* Class ShutDownListener
*
* @since 2.0
*
* @Listener("swoft.wang")
*/
class WangListener implements EventHandlerInterface
{
/**
* @param EventInterface $event
*
* @throws SwoftException
*/
public function handle(EventInterface $event): void
{
$message = $event->getTarget();
$hello = $event->getParam(0);
$world = $event->getParam(1);
var_dump($message,$hello,$world);
CLog::debug('this is a test trigger');
}
}
访问页面 http://192.168.33.50:18306/add 发现结果为 如下 自己触发的事件被自己监听到了,打印出了参数
____ _____ ___ ___
/ __/ _____ / _/ /_ |_ | / _ \
_\ \| |/|/ / _ \/ _/ __/ / __/_/ // /
/___/|__,__/\___/_/ \__/ /____(_)___/
SERVER INFORMATION(v2.0.9)
********************************************************************************
* HTTP | Listen: 0.0.0.0:18306, Mode: Process, Worker: 6, Task worker: 12
********************************************************************************
HTTP Server Start Success!
2020/07/17-21:06:09 [INFO] Swoft\Server\Server:startSwoole(491) Swoole\Runtime::enableCoroutine
2020/07/17-21:06:09 [INFO] Swoft\Listener\BeforeStartListener:handle(27) Server extra info: pidFile @runtime/swoft.pid
2020/07/17-21:06:09 [INFO] Swoft\Listener\BeforeStartListener:handle(28) Registered swoole events:
start, shutdown, managerStart, managerStop, workerStart, workerStop, workerError, request, task, finish
Server start success (Master PID: 17738, Manager PID: 17743)
string(15) "this is message"
string(5) "hello"
string(5) "world"