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使用匿名函数递归调用(闭包)的主要内容,如果未能解决你的问题,请参考以下文章

php 在 匿名函数中 调用自身。。

php闭包实现函数的自调用,也是递归

浅析PHP中的闭包和匿名函数

匿名函数和闭包规避xdebug限制的函数递归深度限制

JavaScript函数进阶回调函数递归函数闭包函数

从匿名函数(闭包特性)到 PHP 设计模式之容器模式