PHP使用匿名函数递归调用(闭包)
Posted SuperAvalon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP使用匿名函数递归调用(闭包)相关的知识,希望对你有一定的参考价值。
php闭包官方的定义:
匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。
比如在项目中,需要处理具有递归特征的数据报文,
以下示例,JSON数组对象每一个节点为一个产品数据,产品数据可能包含了不同类型的关联产品(示例JSON中的relation_item字段)或关联配件(示例JSON中的relation_part字段),关联产品或配件其实也是一个完整的产品数据结构,
<?php
//JSON数据报文,底部有提供测试数据
$sResponse = '';
$aResponse = json_decode($sResponse, true);
$readCache = true;
defined('MAPI_IMG_HOST') OR define('MAPI_IMG_HOST', 'http://api.local');
$defaultThumbs = [
's' => MAPI_IMG_HOST . "/upload/main/default.png",
'i' => MAPI_IMG_HOST . "/upload/main/default.png",
'm' => MAPI_IMG_HOST . "/upload/main/default.png",
];
//业务代码可以忽略
//定义处理数据的匿名函数,因为需要递归调用自己,因此$func做为参数要放到use里面
$func = function($val) use ($readCache, $defaultThumbs, &$func)
$skuData = [];
$relationItem = [];
$relationPart = [];
//$downImageRetval = $this->downImage($val['productmainimage'], $readCache);
$baseInfo = [
'type_name' => '',
'brand_pid' => $val['productbrandpid'],
'brand_name' => $val['productbrandname'],
'model_name' => $val['productmodelname'],
'image' => MAPI_IMG_HOST . $val['productmainimage'],
'image_thum' => $downImageRetval['s'] ?? $defaultThumbs['s'],
'image_thum_i' => $downImageRetval['i'] ?? $defaultThumbs['i'],
'image_thum_m' => $downImageRetval['m'] ?? $defaultThumbs['m'],
'desc' => $val['productsummary'],
'unit' => $val['productunit'],
];
if ($val['children'])
foreach ($val['children'] as $k => $v)
$skuData[] = [
'id' => $v['pid'],
'pid' => $val['pid'],
'label' => $val['productname'],
'item' => $v['productcoloritem'],
'price' => $v['productsalesprice'] ?? $v['productcolorprice'],
'low_price' => $v['productlowprice'] ?? 0,
'cost_price' => $v['productcostprice'] ?? 0,
'base' => $baseInfo
];
else
$skuData[] = [
'id' => $val['pid'] . '99',
'pid' => $val['pid'],
'label' => $val['productname'],
'item' => '默认规格',
'price' => 0,
'low_price' => 0,
'cost_price' => 0,
'base' => $baseInfo
];
//如果relation_item有数据,就产生了递归,需要$func调用自己来解析数据
if (isset($val['relation_item']) && $val['relation_item'])
foreach ($val['relation_item'] as $item)
array_push($relationItem, $func($item));
//递归处理relation_part
if (isset($val['relation_part']) && $val['relation_part'])
foreach ($val['relation_part'] as $part)
array_push($relationPart, $func($part));
$aProduct = [
'pid' => $val['pid'],
'name' => $val['productname'],
'brand' => $val['productbrandname'],
'model' => $val['productmodelname'],
'desc' => $val['productsummary'],
'image' => MAPI_IMG_HOST . $val['productmainimage'],
'image_thum' => $downImageRetval['s'] ?? $defaultThumbs['s'],
'image_thum_i' => $downImageRetval['i'] ?? $defaultThumbs['i'],
'image_thum_m' => $downImageRetval['m'] ?? $defaultThumbs['m'],
'sku' => $skuData,
'relation_item' => $relationItem,
'relation_part' => $relationPart,
];
return $aProduct;
;
$aProducts = [];
//数据处理入口,调用$func处理报文数据
foreach ($aResponse['result']['data'] as $key => $val)
array_push($aProducts, $func($val));
//打印处理后的结果
var_dump($aProducts);
"resultCode":"SUCCESS",
"result":
"total":835,
"data":[
"productbrandpid":"1038518770353471488",
"relation_part":[
"productbrandpid":"4941513789561274368",
"productsummary":"阻抗:8Ω 灵敏度:90DB。///颜色:白色 开孔尺寸:180mm。///重量:.1.8kg。///功率:25W(本机)+25W(外接)。///频响范围:20-22000Hz(±3DB)。///包装尺寸:253*253*143mm。///外观尺寸:195mm(直径)100mm(深度)。
",
"productbrandname":"Wise/华尔思",
"productunit":"只",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258069059829760",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"productmainimage":"/maincorp/uploadfile/productimage/164_164/1979267431075149824.jpg",
"productname":"5寸吸顶式背景音乐喇叭",
"productmodelname":"WS-TPZ409",
"pid":"1115920293697585152",
"accessoriesnum":1
,
"productbrandpid":"4941513789561274368",
"productsummary":"阻抗:8Ω 灵敏度:90±2DB。///颜色:白色 开孔尺寸:165mm。///功率:10W 重量:600g。///频响范围:90-20KHz。///包装尺寸:193*193*83mm。///外观尺寸:189(直径)70mm(深度)。
",
"productbrandname":"Wise/华尔思",
"productunit":"只",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258069059829760",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"productmainimage":"/maincorp/uploadfile/productimage/164_164/1876440987103434752.jpg",
"productname":"6.5寸吸顶式背景音乐喇叭",
"productmodelname":"WS-TPZ403 ",
"pid":"1115927482399096832",
"accessoriesnum":1
,
"productbrandpid":"4941513789561274368",
"productsummary":"阻抗:8Ω 灵敏度:91DB。///颜色:白色 开孔尺寸:160mm。///功率:25W 重量:700g。///频响范围:50-22000Hz。///包装尺寸:250*250*110mm。///外观尺寸:180mm(直径)68mm(深度)。
",
"productbrandname":"Wise/华尔思",
"productunit":"只",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258069059829760",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"productmainimage":"/maincorp/uploadfile/productimage/164_164/5768153958271583232.jpg",
"productname":"4寸吸顶式背景音乐喇叭",
"productmodelname":"WS-TPZ405 ",
"pid":"1115932198273187840",
"accessoriesnum":1
],
"productsummary":"面板材质为金属
> 可作为灯控门窗开关和场景开关,联动场景
> 带状态反馈和指示灯以及背光
> 指示灯颜色可根据情景而改变
> 按键字体可单独定制(收费)
> 边框颜色可选黑色、灰色",
"productbrandname":"AIKS/埃克思",
"productunit":"块",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258069059829760",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"relation_item":[
"productbrandpid":"4941513789561274368",
"productsummary":"阻抗:8Ω 灵敏度:90±2DB。///颜色:白色 开孔尺寸:165mm。///功率:10W 重量:600g。///频响范围:90-20KHz。///包装尺寸:193*193*83mm。///外观尺寸:189(直径)70mm(深度)。
",
"productbrandname":"Wise/华尔思",
"productunit":"只",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258069059829760",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"productmainimage":"/maincorp/uploadfile/productimage/164_164/1876440987103434752.jpg",
"productname":"6.5寸吸顶式背景音乐喇叭",
"productmodelname":"WS-TPZ403 ",
"pid":"1115927482399096832"
,
"productbrandpid":"4941513789561274368",
"productsummary":"阻抗:8Ω 灵敏度:91DB。///颜色:白色 开孔尺寸:160mm。///功率:25W 重量:700g。///频响范围:50-22000Hz。///包装尺寸:250*250*110mm。///外观尺寸:180mm(直径)68mm(深度)。
",
"productbrandname":"Wise/华尔思",
"productunit":"只",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258069059829760",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"productmainimage":"/maincorp/uploadfile/productimage/164_164/5768153958271583232.jpg",
"productname":"4寸吸顶式背景音乐喇叭",
"productmodelname":"WS-TPZ405 ",
"pid":"1115932198273187840"
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/991330150966525952.jpg",
"productname":"1开F系列总线开关面板(金属)",
"productmodelname":"TPN-F/M1",
"pid":"1038258083555344384"
,
"productbrandpid":"1038518770353471488",
"relation_part":[
],
"productsummary":"面板材质为塑料
> 可作为灯控门窗开关和场景开关,联动场景
> 带状态反馈和指示灯以及背光
> 指示灯颜色可根据情景而改变
> 按键字体可单独定制(收费)
> 边框颜色可选黑色、灰色",
"productbrandname":"AIKS/埃克思",
"productunit":"块",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258106103922688",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/991448351150866432.jpg",
"productname":"6开F系列总线开关面板(塑料)",
"productmodelname":"TPN-F/S6",
"pid":"1038258119525695488"
,
"productbrandpid":"1038518770353471488",
"relation_part":[
],
"productsummary":"> 面板材质为塑料
> 可作为灯控门窗开关和场景开关,联动场景
> 带状态反馈和指示灯以及背光
> 指示灯颜色可根据情景而改变
> 按键字体可单独定制(收费)
> 边框颜色可选黑色、灰色",
"productbrandname":"AIKS/埃克思",
"productunit":"块",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258142611144704",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/991371421844144128.jpg",
"productname":"4开F系列总线开关面板(塑料)",
"productmodelname":"TPN-F/S4",
"pid":"1038258156569788416"
,
"productbrandpid":"1038518770353471488",
"relation_part":[
],
"productsummary":"> 面板材质为塑料
> 可作为灯控门窗开关和场景开关,联动场景
> 带状态反馈和指示灯以及背光
> 指示灯颜色可根据情景而改变
> 按键字体可单独定制(收费)
> 边框颜色可选黑色、灰色",
"productbrandname":"AIKS/埃克思",
"productunit":"块",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258179655237632",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/991377062209945600.jpg",
"productname":"3开F系列总线开关面板(塑料)",
"productmodelname":"TPN-F/S3",
"pid":"1038258193613881344"
,
"productbrandpid":"1038518770353471488",
"relation_part":[
],
"productsummary":"> 面板材质为塑料
> 可作为灯控门窗开关和场景开关,联动场景
> 带状态反馈和指示灯以及背光
> 指示灯颜色可根据情景而改变
> 按键字体可单独定制(收费)
> 边框颜色可选黑色、灰色",
"productbrandname":"AIKS/埃克思",
"productunit":"块",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258216162459648",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/991382886185598976.jpg",
"productname":"2开F系列总线开关面板(塑料)",
"productmodelname":"TPN-F/S2",
"pid":"1038258231194845184"
,
"productbrandpid":"1038518770353471488",
"relation_part":[
],
"productsummary":"> 面板材质为塑料
> 可作为灯控门窗开关和场景开关,联动场景
> 带状态反馈和指示灯以及背光
> 指示灯颜色可根据情景而改变
> 按键字体可单独定制(收费)
> 边框颜色可选黑色、灰色",
"productbrandname":"AIKS/埃克思",
"productunit":"块",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258254280294400",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/991387600985948160.jpg",
"productname":"1开F系列总线开关面板(塑料)",
"productmodelname":"TPN-F/S1",
"pid":"1038258268238938112"
,
"productbrandpid":"1038518770353471488",
"relation_part":[
],
"productsummary":"可作为灯控门窗开关和场景开关
> 带状态反馈和指示灯以及背光
> 指示灯颜色可根据情景而改变
> 按键字体可单独定制
> 边框颜色可选",
"productbrandname":"AIKS/埃克思",
"productunit":"块",
"children":[
"productsalesprice":"0",
"productcoloritem":"2",
"productstock":0,
"productmainimage":"",
"pid":"1038258291861258240",
"productlowprice":"0",
"productcostprice":"0",
"marketprice":0
],
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200212/164_164/935468461453115392.jpg",
"productname":"T系列总线开关面板",
"productmodelname":"TPN-S4",
"pid":"1038258305819901952"
,
"relation_part":[
],
"productsummary":" CAN-BUS总线接口",
"productbrandname":"AIKS/埃克思",
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/993108537473138688.jpg",
"pid":"1038258451848790016",
"productlowprice":0,
"productcostprice":0,
"productbrandpid":"1038518770353471488",
"productsalesprice":0,
"productunit":"只",
"children":[
],
"productname":"3路0-10V信号放大器",
"productmodelname":"TLD-3A1"
,
"relation_part":[
],
"productsummary":"> 导轨式3路1-10V,PWM输出LED驱动器",
"productbrandname":"AIKS/埃克思",
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/993094096182476800.jpg",
"pid":"1038258476007981056",
"productlowprice":0,
"productcostprice":0,
"productbrandpid":"1038518770353471488",
"productsalesprice":0,
"productunit":"只",
"children":[
],
"productname":"3路0-10V调光驱动器",
"productmodelname":"TLD-3S8"
,
"relation_part":[
],
"productsummary":"> 导轨式单路1-10V(控制灯光色彩65535种颜色切换)
> CAN-BUS总线接口",
"productbrandname":"AIKS/埃克思",
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/993972136747892736.jpg",
"pid":"1038258499630301184",
"productlowprice":0,
"productcostprice":0,
"productbrandpid":"1038518770353471488",
"productsalesprice":0,
"productunit":"只",
"children":[
],
"productname":"1路0-10V(RGB)调光模块",
"productmodelname":"LSS-G1"
,
"relation_part":[
],
"productsummary":"> 导轨式3路1-10V(控制灯光亮度)
> CAN-BUS总线接口",
"productbrandname":"AIKS/埃克思",
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/993950120208662528.jpg",
"pid":"1038258523789492224",
"productlowprice":0,
"productcostprice":0,
"productbrandpid":"1038518770353471488",
"productsalesprice":0,
"productunit":"只",
"children":[
],
"productname":"3路0-10V调光模块",
"productmodelname":"LSS-D/V3"
,
"relation_part":[
],
"productsummary":">5路LED调光输出(控制灯光明暗)
>CAN-BUS总线接口",
"productbrandname":"AIKS/埃克思",
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/991975788704071680.jpg",
"pid":"1038258548485554176",
"productlowprice":0,
"productcostprice":0,
"productbrandpid":"1038518770353471488",
"productsalesprice":0,
"productunit":"只",
"children":[
],
"productname":"5路0-10V调光模块",
"productmodelname":"LSS-D/V5"
,
"relation_part":[
],
"productsummary":">2路调光输出,单路1KW(控制灯光明暗)
>CAN-BUS总线接口",
"productbrandname":"AIKS/埃克思",
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/991957882985414656.jpg",
"pid":"1038258573181616128",
"productlowprice":0,
"productcostprice":0,
"productbrandpid":"1038518770353471488",
"productsalesprice":0,
"productunit":"只",
"children":[
],
"productname":"2路可控硅调光模块",
"productmodelname":"LSS-D/S2"
,
"relation_part":[
],
"productsummary":">8路输出,单路16A(控制灯光开、关)
>CAN-BUS总线接口",
"productbrandname":"AIKS/埃克思",
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/994001500365553664.jpg",
"pid":"1038258597877678080",
"productlowprice":0,
"productcostprice":0,
"productbrandpid":"1038518770353471488",
"productsalesprice":0,
"productunit":"只",
"children":[
],
"productname":"8路功率继电器模块",
"productmodelname":"LSS-P8"
,
"relation_part":[
],
"productsummary":">4路输出,单路30A(控制灯光开、关)
>CAN-BUS总线接口",
"productbrandname":"AIKS/埃克思",
"relation_item":[
],
"productmainimage":"/maincorp/uploadfile/productimage/20200211/164_164/993989689205489664.jpg",
"pid":"1038258623110610944",
"productlowprice":0,
"productcostprice":0,
"productbrandpid":"1038518770353471488",
"productsalesprice":0,
"productunit":"只",
"children":[
],
"productname":"4路功率继电器模块",
"productmodelname":"LSS-P4"
]
,
"message":null,
"date":"2020-06-04 11:50:26"
以上是关于PHP使用匿名函数递归调用(闭包)的主要内容,如果未能解决你的问题,请参考以下文章