用抽象类返回新$

我在代码中发现了一些问题,不明白为什么它会这样做。 任何人都可以解释我?

让我们有:

abstract class AbstractThing
{
    public function search(...)
    {
        $ret = false;

        $data = $database->query(...);
        foreach($data as $values)
        {
            $item  = new $this;
            $item->fill_with_values($values);

            $ret []= $item;
        }

        return $ret;
    }
}

它按预期工作并在成功搜索时返回对象实例:

class Thing extends AbstractThing
{
    // ...
}

$thing = new Thing;
$things = $thing->search(...); // Thing[] on success, false on failure

但是,如果我想稍微缩短代码,它就会破坏:

abstract class AbstractThing
{
    public function search(...)
    {
        $ret = false;

        $data = $database->query(...);
        foreach($data as $values) {
            $ret []= (new $this)->fill_with_values($values);
        }

        return $ret;
    }
}

这个返回布尔值为true。 为什么? 它适用于没有从抽象类继承的类。


当我们分配:

$ret []= (new $this)->fill_with_values($values);

...我们没有设置$ret[] = (new $this) 。 相反,此语句将fill_with_values()的返回值推入数组,因为它最后执行。

它看起来像你试图实现类似于工厂方法模式的东西。 考虑这个:

abstract class AbstractThing
{ 
    ...
    public static function fill($values) 
    { 
        $instance = new static; 
        $instance->fill_with_values($values);

        return $instance; 
    }
}

然后我们可以在你的问题中实际完成你想要完成的任务:

$ret[] = static::fill($values);

这是fill_with_values() ,因为fill()的返回值是类的实例,而不是fill_with_values()的返回值。 这个上下文中的static关键字使用晚期静态绑定来解析执行代码的类的类型(在这种情况下是Thing )而不是声明它的类,所以它通过继承起作用。 看到这个问题了解更多信息。


代码做了两件不同的事情:

这会将$ item添加到您的“$ ret”数组中:

        $item  = new $this;
        $item->fill_with_values($values);

        $ret []= $item;

这会将返回的“fill_with_values”值添加到您的数组中:

$ret []= (new $this)->fill_with_values($values);

上述代码的等价物将是:

        $item  = new $this;
        $return = $item->fill_with_values($values);
        $ret []= $return;

如果我知道你的“fill_with_values”方法发生了什么,我可以告诉你为什么它是一个布尔值,但是代码不会做同样的事情。 希望这是有道理的。


好的,最后这是我自己的错误。 确实有可能在某个时刻从fill_with_values()函数返回TRUE。 对不起所有的坏问题,并感谢您的答案!

链接地址: http://www.djcxy.com/p/58037.html

上一篇: Returning of new $this with abstract classes

下一篇: PHP Late Static Binding in Singleton