此时,假设我有一个类似的课程:
class Sentence {
__construct($content) {
$this->content = $content;
}
public function grab_word($num) {
$words = explode(" ", $this->content);
return $words[$num+1];
}
}
所以给出的界面允许我创建new Sentence
,然后我可以调用grab_word()
类方法来获取句子中的单词:
$sentence = new Sentence("Lorem ipsum dolor sit amet");
echo $sentence->grab_word(2);
但是,我想要做的是添加另一个链式类方法,让我能够将这个词大写。
$sentence->grab_word(2); # -> ipsum
$sentence->grab_word(2)->caps(); # -> IPSUM
显然,这不起作用,因为链式方法需要对象继承。如果我要创建caps()
并链接该函数 - 由于返回不是继承的Sentence
对象,它将返回错误。
总结一下,我的问题是如何实现链接这些方法的能力,但是在需要时仍然会返回一个非对象(比如在我的输出示例中)。
答案 0 :(得分:4)
class Sentence {
function __construct($content) {
$this->content = $content;
}
public function grab_word($num) {
$words = explode(" ", $this->content);
return new Sentence($words[$num+1]);
}
public function caps() {
return new Sentence(strtoupper($this->content));
}
function __toString(){
return $this->content;
}
}
具有__toString方法的对象与字符串完全兼容。它仍然是一个对象,但是,当在字符串上下文中明确使用时,它将转换为字符串。
答案 1 :(得分:3)
从广义上讲,你所要求的是不可能的。为什么不总是返回您有时需要链接方法调用的对象?只需返回new Word($words[ ... ])
,您就会处于更好的位置。
现在,当我说"广泛地说"时,你可以采取一些措施来调用不同的方法,这些方法可能存在于不同的类中。您可以使用__call()
来实现类似于ruby的mixins,但实际上非常低劣。 __call()
只会查看被调用的方法名称,然后在将调用委托给该对象(或引发异常)之前迭代可能的目标列表并查看它们是否响应该方法。
PS:这个问题与继承没有任何关系。方法链接需要返回一个对象,而不仅仅是实现一个继承层次结构。当然,您可以返回$this
,这有意义,但通常会返回另一个对象。
答案 2 :(得分:2)
在某些将String视为对象的语言中,您想要做的是相当合理的。 PHP的灵感来自Perl和C,而设计“string”不是一个对象。
你可以把它封装成一个类:
class Word {
private $content;
function __construct($content){
$this->content=$content;
}
function __toString(){
return $this->content;
}
function caps(){
strtoupper($this->content);
return $this;
}
}
class Sentence {
function grab_word($num)
$words = explode(" ", $this->content);
return new Word($words[$num+1]);
}
}
你也应该看看@chris的答案,因为它为你提供了稍微不同的实现。我建议你不要在没有显式克隆的情况下创建新的对象实例,因为这是浪费资源而PHP的设计侧重于服务器的快速和精确响应。