php 回调,PHP的几种回调写法

PHP几种回调写法

PHP里通过匿名函数写回调是最方便的,但是除了匿名函数方式的回调,PHP还有其它的回调写法。以下是PHP几种回调写法的示例。

1、匿名函数回调

use Workerman\Worker;

require_once __DIR__ . '/Workerman/Autoloader.php';

$http_worker = new Worker("http://0.0.0.0:2345");

// 匿名函数回调

$http_worker->onMessage = function($connection, $data){

// 向浏览器发送hello world

$connection->send('hello world');

};

Worker::runAll();

2、普通函数回调

use Workerman\Worker;

require_once __DIR__ . '/Workerman/Autoloader.php';

$http_worker = new Worker("http://0.0.0.0:2345");

// 匿名函数回调

$http_worker->onMessage = 'on_message';

// 普通函数

function on_mesage($connection, $data){

// 向浏览器发送hello world

$connection->send('hello world');

}

Worker::runAll();

3、类方法作为回调

MyClass.php

class MyClass{

public function __construct(){}

public function onWorkerStart($worker){}

public function onConnect($connection){}

public function onMessage($connection, $message){}

public function onClose($connection){}

public function onWorkerStop($connection){}

}

启动脚本 start.php

use Workerman\Worker;

require_once __DIR__ . '/Workerman/Autoloader.php';

// 载入MyClass

require_once __DIR__.'/MyClass.php';

$worker = new Worker("websocket://0.0.0.0:2346");

// 创建一个对象

$my_object = new MyClass();

// 调用类的方法

$worker->onWorkerStart = array($my_object, 'onWorkerStart');

$worker->onConnect = array($my_object, 'onConnect');

$worker->onMessage = array($my_object, 'onMessage');

$worker->onClose = array($my_object, 'onClose');

$worker->onWorkerStop = array($my_object, 'onWorkerStop');

Worker::runAll();

注意:

以上的代码结构不允许在构造函数里初始化资源(MySQL连接、Redis连接、Memcache连接等),因为$my_object = new MyClass();运行在主进程。以MySQL为例,在主进程初始化的MySQL连接等资源会被子进程继承,每个子进程都可以操作这个数据库连接,但是这些连接在MySQL服务端对应的是同一个连接,会发生不可预期的错误,例如mysql gone away 错误。

以上代码结构如果需要在类的构造函数里初始化资源,可以采用以下写法。

MyClass.php

class MyClass{

protected $db = null;

public function __construct(){

// 假设数据库连接类是MyDbClass

$db = new MyDbClass();

}

public function onWorkerStart($worker){}

public function onConnect($connection){}

public function onMessage($connection, $message){}

public function onClose($connection){}

public function onWorkerStop($connection){}

}

启动脚本 start.php

use Workerman\Worker;

require_once __DIR__ . '/Workerman/Autoloader.php';

$worker = new Worker("websocket://0.0.0.0:2346");

// 在onWorkerStart里初始化类

$worker->onWorkerStart = function($worker){

// 载入MyClass

require_once __DIR__.'/MyClass.php';

// 创建一个对象

$my_object = new MyClass();

// 调用类的方法

$worker->onConnect = array($my_object, 'onConnect');

$worker->onMessage = array($my_object, 'onMessage');

$worker->onClose = array($my_object, 'onClose');

$worker->onWorkerStop = array($my_object, 'onWorkerStop');

};

Worker::runAll();

上面代码结构中onWorkerStart运行时已经是属于子进程,等于每个子进程各自建立自己的MySQL连接,所以不会有共享连接的问题。

这样还有一个好处就是支持业务代码reload。由于MyClass.php是在子进程载入的,根据reload规则业务更改MyClass.php后直接reload即可生效。

4、类的静态方法作为回调

静态类MyClass.php

class MyClass{

public static function onWorkerStart($worker){}

public static function onConnect($connection){}

public static function onMessage($connection, $message){}

public static function onClose($connection){}

public static function onWorkerStop($connection){}

}

启动脚本 start.php

use Workerman\Worker;

require_once __DIR__ . '/Workerman/Autoloader.php';

// 载入MyClass

require_once __DIR__.'/MyClass.php';

$worker = new Worker("websocket://0.0.0.0:2346");

// 调用类的静态方法。

$worker->onWorkerStart = array('MyClass', 'onWorkerStart');

$worker->onConnect = array('MyClass', 'onConnect');

$worker->onMessage = array('MyClass', 'onMessage');

$worker->onClose = array('MyClass', 'onClose');

$worker->onWorkerStop = array('MyClass', 'onWorkerStop');

// 如果类带命名空间,则是类似这样的写法

// $worker->onWorkerStart = array('your\namesapce\MyClass', 'onWorkerStart');

// $worker->onConnect = array('your\namesapce\MyClass', 'onConnect');

// $worker->onMessage = array('your\namesapce\MyClass', 'onMessage');

// $worker->onClose = array('your\namesapce\MyClass', 'onClose');

// $worker->onWorkerStop = array('your\namesapce\MyClass', 'onWorkerStop');

Worker::runAll();

注意:根据PHP的运行机制,如果没用调用new 则不会调用构造函数,另外静态类的方法里面不允许使用$this。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值