如果要自定义一个可以回调的函数, 可以选择利用变量函数帮助实现。
<?php/ 声明回调函数filter, 在0-100的整数中通过自定义条件过滤不要的数字@param callback $fun 须要通报一个函数名称字符串作为参数/function filter( $fun ) {for($i=0; $i <= 100; $i++) {//将参数变量$fun加上一个圆插号$fun(), 则为调用和变量$fun值同名的函数if( $fun($i) )continue;echo $i.39;<br>';}}/ 声明一个函数one, 如果参数是3的倍数就返回true, 否则返回false@param int $num 须要一个整数作为参数/function one($num) {return $num%3 == 0;}/ 声明一个函数two, 如果参数是一个回文数(翻转后还即是自己的数)返回true, 否则返回false@param int $num 须要一个整数作为参数/function two($num) {return $num == strrev($num);}filter("one"); //打印出100以内非3的倍数,参数"one"是函数one()的名称字符串,是一个回调echo '--------------------<br>';filter('two'); //打印出100以内非回文数,参数"two"是函数two()的名称字符串,是一个回调
借助call_user_func_array()函数自定义回调函数
<?php/ 声明一个函数fun(), 功能只输出两个字符串,目的是作为call_user_func_array()回调参数@param string $msg1 须要通报一个字符串作为参数@param string $msg2 须要通报另一个字符串作为参数/function fun($msg1, $msg2) {echo '$msg1 = '.$msg1;echo '<br>';echo '$msg2 = '.$msg2;}/ 通过系统函数call_user_func_array() 调用函数fun()第一个参数为函数fun()的名称字符串第二个参数则是一个数组,每个元素值会按顺序通报给调用的fun()函数参数列表中/call_user_func_array('fun', array('LAMP', '张三'));
<?php/ 声明回调函数filter, 在0-100的整数中通过自定义条件过滤不要的数字@param callback $fun 须要通报一个函数名称字符串作为参数/function filter( $fun ) {for($i=0; $i <= 100; $i++) {//利用系统函数call_user_func_array(),调用变量$fun值相同的函数if( call_user_func_array($fun, array($i)) )continue;echo $i.'<br>';}}/ 声明一个函数one, 如果参数是3的倍数就返回true, 否则返回false@param int $num 须要一个整数作为参数/function one($num) {return $num%3 == 0;}/ 声明一个函数two, 如果参数是一个回文数(翻转后还即是自己的数)返回true, 否则返回false@param int $num 须要一个整数作为参数/function two($num) {return $num == strrev($num);}filter("one"); //打印出100以内非3的倍数,参数"one"是函数one()的名称字符串,是一个回调echo '--------------------<br>';filter('two'); //打印出100以内非回文数,参数"two"是函数two()的名称字符串,是一个回调
类静态函数和工具的方法回调
<?php/ 声明一个类Demo,类中声明一个静态的成员方法fun() /class Demo {static function fun($msg1, $msg2) {echo '$msg1 = '.$msg1;echo '<br>';echo '$msg2 = '.$msg2;}}/ 声明一个类Test, 类中声明一个普通的成员方法fun() /class Test {function fun($msg1, $msg2) {echo '$msg1 = '.$msg1;echo '<br>';echo '$msg2 = '.$msg2;}}/ 通过系统函数call_user_func_array()调用Demo类中的静态成员方法fun(),回调类中的成员方法:第一个参数必须利用数组,并且这个数组须要指定两个元素,第一个元素为类名称字符串,第二个元素则是该类中的静态方法名称字符串。第二个参数也是一个数组,这个数组中每个元素值会按顺序通报给调用Demo类中的fun()方法参数列表中。/call_user_func_array( array("Demo", 'fun'), array('LAMP', '兄弟连') );/ 通过系统函数call_user_func_array()调用Test类的实例工具中的成员方法fun(),回调类中的成员方法:第一个参数必须利用数组,并且这个数组须要指定两个元素,第一个元素为工具引用,在本例也可以是$obj=new Test()中的$obj, 第二个元素则是该工具中的成员方法名称字符串。第二个参数也是一个数组,这个数组中每个元素值会按顺序通报给调用new Test()工具中的fun()方法参数列表中。/call_user_func_array( array(new Test(), 'fun'), array('BroPHP', '学习型PHP框架') );
call_user_func()方法利用
<?php//先引用后增加function _call($call){//通过传参获取call_user_func传过来的参数echo $call++,'<br/>';echo $call++,"<br/>";}//上面回调函数没有返回值,以是,这里就没有返回值,_call为上面的函数的名称$re = call_user_func('_call',1);//实验结果为 null,符合上面的结论var_dump($re);?>
<?php//先增加后引用call_user_func(function($call){echo ++$call,'<br/>';echo ++$call,'<br/>';},1);//传给匿名函数的参数为···1···,实行的结果为2,3?>
参考:
<?phpnamespace app\portal\adapter;abstract class AbstractAdapter{//要调用的方法protected $invokes;/ 调用invokes里的类和方法 @param $method @param $params @param $break @return array/protected function callInvokes($method, $params = [], $break = true){ $params = (array)$params; $data = []; foreach ($this->invokes as $className) { if (class_exists($className)) { $class = new $className(); if (method_exists($class, $method)) { $result = call_user_func_array([$class, $method], $params); if ($result) { $data = array_merge($data, $result); if ($break === true || $break === $className) { break; } } } } } return $data; }}
利用方法
<?phpnamespace app\portal\adapter\marketspider;use app\portal\adapter\AbstractAdapter;use think\Db;class Spider extends AbstractAdapter{protected $invokes = [ BishijieSpider::class, //获取app\portal\adapter\marketspider\BishijieSpider类 GateioSpider::class,];protected $marketCoinData;public function getMarketCoin(){ if (! $this->marketCoinData) { $this->marketCoinData = $this->callInvokes('getMarketCoin', [], true); $this->marketCoinData = array_column($this->marketCoinData, null, 'code'); } return $this->marketCoinData;}/ 更新币种到数据库 @param bool $update @return array @throws \think\Exception/public function setMarketCoinToDatabase($update = false){ $data = $this->getMarketCoin(); $query = Db::name('coin'); $insertData = []; foreach ($data as $v) { $code = strtoupper($v['code']); $where = ['code' => $code]; $count = $query->where($where)->count(); $arr = array_filter([ 'code' => $code, 'name' => getVar($v, 'name'), 'name_ch' => getVar($v, 'name_ch'), 'name_en' => getVar($v, 'name_en'), 'source_code' => getVar($v, 'source_code'), 'source' => getVar($v, 'source'), 'total_value' => getVar($v, 'total_value'), 'addtime' => time(), ]); if (! $count) { $insertData[] = $arr; } else if ($update) { $query->where($where)->update($arr); } } $insertData && $query->insertAll($insertData); return $data;}/ 更新行情信息到数据库 @return array @throws \think\Exception/public function setMarketInfoToDatabase(){ $data = $this->getMarketCoin(); $query = Db::name('market_info'); $insertData = []; foreach ($data as $v) { $code = strtoupper($v['code']); $where = ['coin' => $code]; $count = $query->where($where)->count(); $arr = array_filter([ 'coin' => $code, 'market' => strtolower($code) .'_'. 'usdt', 'last_price' => getVar($v, 'price'), 'rate' => getRmbRate(), 'percentchange' => getVar($v, 'percentchange'), 'basevolume' => getVar($v, 'basevolume'), 'addtime' => time(), ]); if (! $count) { $insertData[] = $arr; } else { $query->where($where)->update($arr); } } $insertData && $query->insertAll($insertData); return $data;}public function updateAll($update = false){ $this->setMarketCoinToDatabase($update); $this->setMarketInfoToDatabase();}}