不在对象上下文中时使用$ this ...堆栈问题?

时间:2012-01-23 13:07:36

标签: php

使用下面的代码时,我收到错误在不在对象上下文中时使用$ this 。这是因为函数在堆栈上并且无法访问对象吗?

array_walk($pins, function (&$array) {
$array->timestamp = $this->convertTime(strtotime($array->timestamp));
});

解决这个问题的最佳方法是什么?我正在考虑使用foreach,但想要了解更多适合此目的的PHP较少使用的函数。

解决了
foreach($pins as $pin) {
    $pin->timestamp = $this->convertTime(strtotime($pin->timestamp));
}

但我仍然想知道如何解决array_walk的问题。

4 个答案:

答案 0 :(得分:4)

试试这个:

$that =& $this;
array_walk($pins, function (&$array) use ($that) {
  $array->timestamp = $that->convertTime(strtotime($array->timestamp));
});

此外,如果您实际上是在走一个数组,那么正确的语法可能是:

$that =& $this;
array_walk($pins, function (&$array) use ($that) {
  $array['timestamp'] = $that->convertTime(strtotime($array['timestamp']));
});

答案 1 :(得分:0)

原因是你传递的是一个不属于对象的普通函数。由于没有对象,$this无法指出。如果convertTime在全局范围内,则只需省略$this->。不过,请考虑passing an object as a callbackarray_walk

答案 2 :(得分:0)

  

解决这个问题的最佳方法是什么?我正在考虑使用foreach,但想要了解更多适合此目的的PHP较少使用的函数。

我会说,对于你的情况,foreach是一个非常好的解决方案,因为它清楚它的作用。您可能希望使用您的示例模仿别名array_walk商品:

foreach($pins as &$pin) {
    $pin->timestamp = $this->convertTime(strtotime($pin->timestamp));
}
unset($pin);

这应该更接近array_walk。可能你也想引用数组本身(可能):

$pinsRef = &$pins;
foreach($pinsRef as &$pin) {
    $pin->timestamp = $this->convertTime(strtotime($pin->timestamp));
}
unset($pin);

如果要将对象本身($this)封装在具有私有访问权限的匿名函数中,则无法实现。因为在匿名函数的上下文中不存在任何$this(但是,后来的PHP版本可能会有这种情况)。

但是,一种解决方法是通过使用use子句将对象实例传递到匿名函数的本地范围。

$_this = $this;
$callback = function (&$array) use ($_this) {
    $array->timestamp = $_this->convertTime(strtotime($array->timestamp));
});
array_walk($pins, $callback);

但是这种解决方法是有限的,因为$this的私人成员无法访问。相反,你可以创建回调函数作为对象的一部分并指定它,然后可以进行私有访问,你可以像任何其他对象回调一样调用它:

array_walk($pins, array($this, 'callback'));

这让我回到开头说foreach可能是比array_walk更好的选择武器。

我希望这有助于向您展示不同的替代方案。

答案 3 :(得分:0)

从PHP 5.4.0开始,您可以从匿名函数内部访问$ this。