在PHP爲什麼我不能做:調用對象的方法,在創建實例
class C
{
function foo() {}
}
new C()->foo();
,但我必須這樣做:
$v = new C();
$v->foo();
在所有的語言,我可以做到這一點...
在PHP爲什麼我不能做:調用對象的方法,在創建實例
class C
{
function foo() {}
}
new C()->foo();
,但我必須這樣做:
$v = new C();
$v->foo();
在所有的語言,我可以做到這一點...
在PHP中,你不能將新創建的對象上調用的方法沒有像new Foo()->someMethod();
對不起,但事實就是如此。
但是你可以圍繞着建立一個工作是這樣的:
<?php
class CustomConstructor
{
public static function customConstruct($methodName)
{
$obj = new static; //only available in PHP 5.3 or later
call_user_method($methodName, $obj);
return $obj;
}
}
擴展CustomContructor這樣的:
class YourClass extends CustomConstructor
{
public function someCoolMethod()
{
//cool stuff
}
}
和實例他們是這樣的:
$foo = YourClass::customConstruct('someCoolMethod');
我沒有測試過它但它或類似的東西應該工作。
更正:這將只適用於PHP 5.3及更高版本,因爲需要後期靜態綁定。
我嘗試這樣做,是成功的 -
<?php
$obj = new test("testFunc");
class test{
function __construct($funcName){
if(method_exists($this, $funcName)){
self::$funcName();
}
}
function testFunc(){
echo "blah";
return $this;
}
}
?>
從PHP 5.4開始,你可以做
(new Foo)->bar();
在此之前,這是不可能的。見
但你有一些一些替代品
令人難以置信的是醜陋的解決方案我無法解釋:
end($_ = array(new C))->foo();
毫無意義的序列化/反序列化只是爲了能夠給鏈
unserialize(serialize(new C))->foo();
同樣毫無意義的方法使用反射
call_user_func(array(new ReflectionClass('Utils'), 'C'))->foo();
某種程度上更理智的使用方法函數作爲一個工廠:
// global function
function Factory($klass) { return new $klass; }
Factory('C')->foo()
// Lambda PHP < 5.3
$Factory = create_function('$klass', 'return new $klass;');
$Factory('C')->foo();
// Lambda PHP > 5.3
$Factory = function($klass) { return new $klass };
$Factory('C')->foo();
最健全的方法使用Factory Method Pattern解決方案:
class C { public static function create() { return new C; } }
C::create()->foo();
你不應該能夠像
new C()->foo();
執行代碼,至少不是隻要這種語言準確地遵循邏輯。該對象不是僅使用C()
創建的,而是使用完整的new C()
創建的。因此,你應該假設可以,如果你有另外一對括號來執行該代碼: (new C())->foo();
(警告:我沒有測試過上述情況,我只是說這應該假設工作)
大多數語言(我遇到過)以相同的方式處理這種情況。 C,C#,Java和德爾福...
不幸的是,這是行不通的。 PHP不是C,C#,JAVA,DELPHI等 – user187291 2010-03-29 19:43:57
嗯,單數。我真的可以發誓我已經在PHP中做過這種事情了。好吧! – JMTyler 2010-03-29 23:27:27
不正確。基於運算符優先級表,新的an()首先被執行。其他語言也以同樣的方式工作。所以在Java,C#等,如果你做新的C()。foo()一切正常! – xdevel2000 2010-03-30 08:33:27
從PHP 5.4,你可以這樣做:(new Foo())->someMethod();
見call_user_method手冊部分以瞭解更多內容。 – selfawaresoup 2010-03-29 09:53:23
另外PHP 6不會有這個? – xdevel2000 2010-03-29 09:55:17
我不知道這個問題是否會在PHP6中修復。無論如何,直到6出來還有很長一段時間。 – selfawaresoup 2010-03-29 09:56:22