PHP方法链接的最后一个对象 [英] PHP Last Object of Method Chaining

查看:72
本文介绍了PHP方法链接的最后一个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用方法链的PHP中,在链中最后一个方法被调用之后,如何进行功能调用?

In PHP using method chaining how would one go about supplying a functional call after the last method being called in the chain?

也使用相同的实例(见下文).这会杀死实现析构函数的想法.

Also while using the same instance (see below). This would kill the idea of implementing a destructor.

最终结果是从定义的链属性(当然)返回私有私有"insert()"的返回值和函数调用,而不必公开调用它(无论顺序如何).

The end result is a return value and functional call of private "insert()" from the defined chain properties (of course) without having to call it publicly, no matter of the order.

请注意,如果我将(__toString)方法一起回显,它将检索最终生成的唯一代码,这是强制转换字符串的正常行为.

Note, if I echo (__toString) the methods together it would retrieve the final generated unique code which is normal behavior of casting a string.

以下示例:

class object
{
    private $data;
    function __construct($name) {
        // ... some other code stuff
    }

    private function fc($num) {
        // some wicked code here
    }

    public function green($num) {
        $this->data .= fc($num*10);
        return $this;
    }
    public function red($num) {
        $this->data .= fc($num*25);
        return $this;
    }
    public function blue($num) {
        $this->data .= fc($num*1);
        return $this;
    }

    // how to get this baby to fire ?
   private function insert() {
          // inserting
          file_put_content('test_code.txt', $this->data);
   }
}

$tss = new object('index_elements');

$tss->blue(100)->green(200)->red(100);       // chain 1
$tss->green(0)->red(100)->blue(0);           // chain 2
$tss->blue(10)->red(80)->blue(10)->green(0); // chain 3

1 2 3 会根据方法的所有值生成唯一的代码,并提供操作,例如自动插入数据库或创建文件(在此示例中使用).

Chain 1, 2, and 3 would generated an unique code given all the values from the methods and supply an action, e.g. automatically inserting in DB or creating a file (used in this example).

如您所见,没有设置字符串,也没有进行强制类型转换或回显.

As you can see no string setting or casting or echoing is taking place.

推荐答案

您可以保留需要初始化的事物的列表以及它们是否 在这种情况下是否如此.然后每次使用时检查清单 初始化方法之一.像这样:

You could keep a list of things that needs to be initialised and whether they have been so in this instance or not. Then check the list each time you use one of the initialisation methods. Something like:

class O {
    private $init = array
        ( 'red' => false
        , 'green' => false
        , 'blue' => false
        );

    private function isInit() {
        $fin = true;
        foreach($this->init as $in) {
            $fin = $fin && $in;
        }
        return $fin;
    }

    public function green($n) {
        $this->init['green'] = true;
        if($this->isInit()) {
            $this->insert();
        }
    }

    public function red($n) {
        $this->init['red'] = true;
        if($this->isInit()) {
            $this->insert();
        }
    }

    public function blue($n) {
        $this->init['blue'] = true;
        if($this->isInit()) {
            $this->insert();
        }
    }

    private function insert() {
        echo "whee\n";
    }
}

但就我个人而言,这将是不那么值得的麻烦.更好的imo 公开您的insert方法,并让您的代码用户知道何时 初始化完成.所以应该使用这样的东西:

But personally I think this would be more hassle then it's worth. Better imo to expose your insert method and let the user of you code tell when the initialisation is finished. So something that should be used like:

$o->red(1)->green(2)->blue(0)->insert();

-更新-

如果是这种情况,则无法预测需要调用哪些函数 您确实需要对此进行明确说明.我看不到解决的办法.原因 是php真的无法分辨两者之间的区别

If it's the case that it's impossible to predict what functions need to be called you really do need to be explicit about it. I can't see a way around that. The reason is that php really can't tell the difference between

$o1 = new A();
$o2 = $o1->stuff();

$o2 = (new A())->stuff();

用允许超载的语言=我想这是有可能的,但实际上 确实令人困惑,而且通常不是一个好主意.

In a language that allows overloading = I guess it would be possible but really really confusing and generally not a good idea.

可以移动显式部分,使其不在调用结束时 连锁店,但我不确定这是否会让您更快乐?它也会违背 您不想使用其他实例的愿望.看起来可能像这样:

It is possible to move the explicit part so that it's not at the end of the call chain, but I'm not sure if that would make you happier? It would also go against your desire to not use another instance. It could look something like this:

class O {
    public function __construct(InitO $ini) {
        // Do stuff
        echo "Whee\n";
    }
}

class InitO {
    public function red($n) {
        return $this;
    }
    public function green($n) {
        return $this;
    }
    public function blue($n) {
        return $this;
    }
}

$o = new O((new InitO())->red(10)->red(9)->green(7));

您当然可以通过使用其他包装方式来仅使用一个实例 但是我现在唯一能想到的方法看起来很丑.

You can of course use just one instance by using some other way of wrapping but the only ways I can think of right now would look a lot uglier.

这篇关于PHP方法链接的最后一个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆