【问题标题】:Having trouble understanding why my Closure wasn't working无法理解为什么我的 Closure 不起作用
【发布时间】:2020-04-12 02:16:35
【问题描述】:

我在 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 (&amp;$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();
    }

}

我不知道为什么第二个应该有效,但第一个无效。有人能解释一下吗?

【问题讨论】:

    标签: php laravel closures


    【解决方案1】:

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

    这样你就有了函数声明,在这种情况下是在另一个函数或方法中。

    这是不允许的,因此肯定会给你 500。

    如果你检查你的 php error_log 并且可能是你的 laravel 日志。它会告诉你的。

    如果此时你不想将它分配给变量,你可以立即返回它

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多