【问题标题】:Why can't I use 'use' in non-anonymous functions?为什么我不能在非匿名函数中使用“使用”?
【发布时间】:2017-12-04 15:31:13
【问题描述】:

我正在尝试从父子元素数组创建路径。

这个想法是编写一个递归函数,它用路径包含的所有元素按顺序填充一个数组。

我的问题在于 PHP 中的闭包:

为了让我的递归函数工作,我必须在全局范围内定义几个变量。

看起来是这样的:

global $breadcrumbs;
$breadcrumbs = array();
function buildBreadcrumbs($elements, $parentID){
    global $siteroot;
    global $breadcrumbs;
    global $navigation;
    if($siteroot['id'] === $parentID){
        $nav = array_values($navigation);
        array_unshift($breadcrumbs, array('label' => 'Start', 'id' => $nav[0]['id']));
    } else {
        foreach ($elements as $element) {
            if ($element['id'] === $parentID) {
                array_unshift($breadcrumbs, array('label' => $element['navlabel'], 'id' => $element['id']));
                buildBreadcrumbs($elements, $element['parent'][0]);
            }
        }
    }
}

我尝试以这种方式使用 'use' 关键字而不是全局变量:

function buildBreadcrumbs($elements, $parentID) use($siteroot, $breadcrumbs, $navigation){
        if($siteroot['id'] === $parentID){
            $nav = array_values($navigation);
            array_unshift($breadcrumbs, array('label' => 'Start', 'id' => $nav[0]['id']));
        } else {
            foreach ($elements as $element) {
                if ($element['id'] === $parentID) {
                    array_unshift($breadcrumbs, array('label' => $element['navlabel'], 'id' => $element['id']));
                    buildBreadcrumbs($elements, $element['parent'][0]);
                }
            }
        }
    }

但这给了我语法错误:

PHP Parse error: syntax error, unexpected T_USE, expecting '{'

我在这里做错了什么?

为什么$breadcrumbs 首先必须是全局的,这样函数才能使用它?

【问题讨论】:

  • 该函数是其自身的局部变量,它无法访问外部变量,除非您选择向其添加参数。这就是它无法访问$breadcrumbs 的原因——因为它超出了范围
  • 为什么不将变量传递给函数?

标签: php recursion closures


【解决方案1】:

如果你的变量都只用在这个类中,你可以使用 $this 关键字。

例子:

private $breadcrumbs = array();
private $siteroot;
private $navigation;

function buildBreadcrumbs($elements, $parentID){
    if($this->siteroot['id'] === $parentID){
        $nav = array_values($this->navigation);
        array_unshift($this->breadcrumbs, array('label' => 'Start', 'id' => $nav[0]['id']));
    } else {
        foreach ($elements as $element) {
            if ($element['id'] === $parentID) {
                array_unshift($this->breadcrumbs, array('label' => $element['navlabel'], 'id' => $element['id']));
                buildBreadcrumbs($elements, $element['parent'][0]);
            }
        }
    }
}

如果它们是真正的全局变量,那么您必须将它们用作全局变量。或者在此之后创建一个函数,用你的类变量(你用 $this 关键字更新)更新你的全局变量。

【讨论】:

  • OP 没有使用类。
【解决方案2】:

对于匿名函数,您不是从全局范围导入变量,而是从父范围导入变量。

一个很大的区别是:

$global = 123;
function parent() {
   $parent = 123;
   $closure = function() use ($parent, $global) {
      // $global won't exist, but $parent will.
   }
}

命名函数与闭包没有相同的“父”作用域。

从父作用域继承变量与使用不同 全局变量。全局变量存在于全局范围内,即 无论执行什么功能都是一样的。 a 的父作用域 闭包是声明闭包的函数

在此处查看示例 #4:http://php.net/manual/en/functions.anonymous.php

【讨论】:

    猜你喜欢
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 2021-05-13
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    相关资源
    最近更新 更多