无法访问传递给对象方法的 PHP 闭包上的$this

Can't access $this on PHP Closure passed to an object method

提问人:José Eduardo Biasioli 提问时间:4/22/2021 更新时间:4/22/2021 访问量:114

问:

我正在尝试传递一个使用对象数据的闭包,而不必将对象分配给变量并将其作为参数传递给闭包,但我似乎无法找出正确的方法。

这是我的任意类代码:

class Person
{
    var $__data = [];

    function setData($key, $value)
    {
        $this->__data[$key] = $value;
        return $this;
    }

    function setAutoData($map)
    {
        $this->__data = array_merge($this->__data, $map());
        return $this;
    }

    function getData($key)
    {
        return $this->__data[$key];
    }

}

这里的这段代码将起作用,并将first_name添加到数据数组中:

$p = (new Person())->setData('full_name', 'Valerie Maddison Bricks');

print_r($p->setAutoData(function () use($p) {
    return [
        'first_name' => array_shift(explode(' ', $p->getData('full_name')))
    ];
}));

/*
Output:

Person Object
(
    [__data] => Array
        (
            [full_name] => Valerie Maddison Bricks
            [first_name] => Valerie
        )

)
*/

这个行不通

print_r((new Person())
            ->setData('full_name', 'Valerie Maddison Bricks')
            ->setAutoData(function () {
                return [
                    'first_name' => array_shift(explode(' ', $this->getData('full_name'))),
                ];
            }));

/*
Output:
Fatal error:  Uncaught Error: Using $this when not in object context in C:\Damian\xampp\web\dbo-dev\teste.php:44
Stack trace:
#0 C:\Damian\xampp\web\dbo-dev\teste.php(22): {closure}()
#1 C:\Damian\xampp\web\dbo-dev\teste.php(46): Person->setAutoData(Object(Closure))
#2 {main}
  thrown in C:\Damian\xampp\web\dbo-dev\teste.php on line 44
*/

有没有办法在不依赖变量的情况下以类似的方式实现这一点?

PHP 关闭了 这个

评论

3赞 RiggsFolly 4/22/2021
小点从 PHP 4 开始不用于声明属性。检查 21 世纪的方式var

答:

2赞 Syscall 4/22/2021 #1

为了避免使用 ,可以传入闭包的调用。但是您不能在匿名函数中使用。$p$this$this

$this->__data = array_merge($this->__data, $map($this));

然后

->setAutoData(function ($object) {
    $array = explode(' ', $object->getData('full_name'));
    return [
        'first_name' => array_shift($array),
    ];
})

请注意,这需要引用。您应该为此创建一个变量。array_shift

法典:

class Person
{
    private $__data = [];

    public function setData($key, $value)
    {
        $this->__data[$key] = $value;
        return $this;
    }

    public function setAutoData($map)
    {
        $this->__data = array_merge($this->__data, $map($this));
        return $this;
    }

    public function getData($key)
    {
        return $this->__data[$key];
    }

}

print_r(
    (new Person())
    ->setData('full_name', 'Valerie Maddison Bricks')
    ->setAutoData(function ($object) {
        $array = explode(' ', $object->getData('full_name'));
        return [
            'first_name' => array_shift($array),
        ];
    })
);

输出:

Person Object
(
    [__data:Person:private] => Array
        (
            [full_name] => Valerie Maddison Bricks
            [first_name] => Valerie
        )

)