无法理解为什么我的关闭无法正常工作

时间:2019-12-19 13:10:09

标签: php laravel closures

我在laravel中有一个控制器AppExportController。在该控制器上的功能之一中,我遍历了许多记录并返回了文件下载。我决定要创建一个小函数,以便可以在此实例中缓存某个东西,即“区域名称”。

这是我第一次尝试编写用于缓存区域名称的函数(显然是getZoneName函数):

<?php

namespace App\Http\Controllers;

class AppExportController extends Controller {
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct() {
        $this->middleware('auth');
        $this->middleware('client.approved');
    }

    public function prices(Request $request) {
        $user = Auth::user();
        ...

        $zoneNameCache = [];
        function getZoneName($zoneId) use (&$zoneNameCache) {
            try {
                if (!empty($zoneNameCache[$zoneId])) {
                    return $zoneNameCache[$zoneId];
                } else {
                    $zone = ServiceZone::find($zoneId);
                    $zoneNameCache[$zoneId] = $zone->name;
                    return $zone->name;
                }
            } catch(Exception $e) {
                return '';
            }
        };


        $prices = []; // I actually do a database query here, don't worry about that
        $records = [];

        foreach($prices as $price) {
            // output to $records here
            $records[] = [
                ...
                getZoneName($price->service_zone_id),
                ...
            ];
        }

        return response();
    }

}

这使该路由500出错,并且我一直追踪到它可以确定该函数的关闭方面-当我取出use (&$zoneNameCache)部分时,它起作用了(但没有缓存任何内容)当然)。

所以我尝试了另一件事-将函数分配给变量。那行得通!关闭后,缓存就开始工作了!

<?php

namespace App\Http\Controllers;

class AppExportController extends Controller {
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct() {
        $this->middleware('auth');
        $this->middleware('client.approved');
    }

    public function prices(Request $request) {
        $user = Auth::user();
        ...

        $zoneNameCache = [];
        $getZoneName = function ($zoneId) use (&$zoneNameCache) {
            try {
                if (!empty($zoneNameCache[$zoneId])) {
                    return $zoneNameCache[$zoneId];
                } else {
                    $zone = ServiceZone::find($zoneId);
                    $zoneNameCache[$zoneId] = $zone->name;
                    return $zone->name;
                }
            } catch(Exception $e) {
                return '';
            }
        };


        $prices = []; // I actually do a database query here, don't worry about that
        $records = [];

        foreach($prices as $price) {
            // output to $records here
            $records[] = [
                ...
                $getZoneName($price->service_zone_id),
                ...
            ];
        }

        return response();
    }

}

我不知道第二个为什么应该工作,但第一个为什么不工作。有人可以阐明这一点吗?

1 个答案:

答案 0 :(得分:2)

如果不将其分配给变量或返回变量,则它不是闭包。

这样,在这种情况下,您可以在另一个函数或方法中进行函数声明。

不允许这样做,因此肯定会给您500。

如果您检查您的php error_log以及您的laravel日志。它会告诉你。

如果您当时不想将其分配给变量,则可以立即将其返回

返回函数().......