如何在新创build的对象上链接方法?
我想知道是否有一种方法链接PHP中新创build的对象的方法?
就像是:
class Foo { public function xyz() { ... return $this; } } $my_foo = new Foo()->xyz();
任何人都知道一个方法来实现这一目标?
在PHP 5.4+中,parsing器已被修改,所以你可以做这样的事情
(new Foo())->xyz();
将括号中的实例括起来,并链接起来。
在PHP 5.4之前,当你使用
new Classname();
语法,你不能链接一个方法调用实例化。 这是PHP 5.3语法的限制。 一旦一个对象被实例化,你可以链接。
我见过的一个方法是用来解决这个问题的,就是某种静态的实例化方法。
class Foo { public function xyz() { echo "Called","\n"; return $this; } static public function instantiate() { return new self(); } } $a = Foo::instantiate()->xyz();
通过在静态方法中将调用包装为new,可以使用方法调用实例化一个类,然后您可以自由地将其链接起来。
定义一个像这样的全局函数:
function with($object){ return $object; }
您将可以打电话给:
with(new Foo)->xyz();
在PHP 5.4中,你可以链接一个新实例化的对象:
http://docs.php.net/manual/en/migration54.new-features.php
对于旧版本的PHP,您可以使用Alan Storm的解决scheme。
这个答案已经过时 – 所以想纠正它。
在PHP 5.4.x中,你可以将一个方法链接到一个新的调用。 我们以这个class级为例:
<?php class a { public function __construct() { echo "Constructed\n"; } public function foo() { echo "Foobar'd!\n"; } }
现在,我们可以使用这个: $b = (new a())->foo();
输出是:
Constructed Foobar'd!
更多信息可在手册中find: http : //www.php.net/manual/en/migration54.new-features.php
那么,这可能是一个老问题,但与编程中的很多事情一样 – 最终答案会改变。
关于PHP 5.3,不,你不能直接链接构造函数。 然而,为了扩大接受的答案,为了适应inheritance,你可以做:
abstract class Foo { public static function create() { return new static; } } class Bar extends Foo { public function chain1() { return $this; } public function chain2() { return $this; } } $bar = Bar::create()->chain1()->chain2();
这将工作得很好,并会返回一个新的Bar()实例。
然而,在PHP 5.4中,你可以简单地做:
$bar = (new Bar)->chain1()->chain2();
希望这有助于像我一样绊倒问题的人!
如果他们在未来的版本中“解决这个问题”将会非常有帮助。 我真的很感激能力链(尤其是当填充集合):
我在我的框架的基类中添加了一个名为create()的方法,该方法可以被链接。 应该自动处理所有的后代类。
class baseClass { ... public final static function create() { $class = new \ReflectionClass(get_called_class()); return $class->newInstance(func_get_args()); } ... public function __call($method, $args) { $matches = array(); if (preg_match('/^(?:Add|Set)(?<prop>.+)/', $method, $matches) > 0) { // Magic chaining method if (property_exists($this, $matches['prop']) && count($args) > 0) { $this->$matches['prop'] = $args[0]; return $this; } } } ... }
类::创build() – > SETNAME( '克里斯') – > SetAge(36);
只是为了完整性(为了它的乐趣…),因为没有人似乎用最短(也是最复杂的)代码提到了解决scheme。
对于经常使用的短期对象,特别是在编写测试用例时,通常会进行大量的对象创build,为了便于打字(而不是纯度),可以优化,并将Alan Storm的Foo::instantiate()
工厂方法和Kenaniah的with()
全局函数技术。
只需使工厂方法成为与class级同名的全局函数! 。 ; -o(或者把它作为一个方便的包装添加到正确的静态Foo::instantiate()
或者在没有人看的时候把它移动到那里)。
class Foo { public function xyz() { echo "Called","\n"; return $this; } } function Foo() { return new Foo(); } $a = Foo()->xyz();
注意:
- 我不会在生产代码上做这件事。 虽然有点性感,但这是对基本编码原则的滥用(比如“最不可思议的原则”(虽然这实际上是相当直观的语法),或者“不要重复自己”,尤其是如果用一些真正的工厂方法参数,它本身,BTW,已经是DRY的滥用…),再加上PHP可能会改变在未来以这种有趣的方式破坏代码。