calling a method of an object at instance creation
In PHP why can't I do:
开发者_如何转开发class C
{
function foo() {}
}
new C()->foo();
but I must do:
$v = new C();
$v->foo();
In all languages I can do that...
Starting from PHP 5.4 you can do
(new Foo)->bar();
Before that, it's not possible. See
- One of many question asking the same on SO
- Discussion on PHP Internals
- Another Discussion on PHP Internals
- Relevant Feature Request in BugTracker
But you have some some alternatives
Incredibly ugly solution I cannot explain:
end($_ = array(new C))->foo();
Pointless Serialize/Unserialize just to be able to chain
unserialize(serialize(new C))->foo();
Equally pointless approach using Reflection
call_user_func(array(new ReflectionClass('Utils'), 'C'))->foo();
Somewhat more sane approach using Functions as a Factory:
// 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();
Most sane approach using Factory Method Pattern Solution:
class C { public static function create() { return new C; } }
C::create()->foo();
From PHP 5.4 you CAN do: (new Foo())->someMethod();
In PHP, you can't call an arbitrary method on a freshly created object like new Foo()->someMethod();
Sorry, but that's the way it is.
But you could build a work around like this:
<?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;
}
}
Extend CustomContructor like this:
class YourClass extends CustomConstructor
{
public function someCoolMethod()
{
//cool stuff
}
}
And instantiate them like this:
$foo = YourClass::customConstruct('someCoolMethod');
I have not tested it but this or something like it should work.
Correction: This will only work in PHP 5.3 and later since late static binding is required.
You should not be able to execute code like
new C()->foo();
in other languages, at least not as long as that language accurately follows logic. The object is not just created using C()
, but with the full new C()
. Therefore, you should hypothetically be able to execute that code if you include another pair of parentheses:
(new C())->foo();
(Be warned: I haven't tested the above, I'm just saying it should hypothetically work.)
Most languages (that I've encountered) deal with this situation the same way. C, C#, Java, Delphi...
I tried this and was successful -
<?php
$obj = new test("testFunc");
class test{
function __construct($funcName){
if(method_exists($this, $funcName)){
self::$funcName();
}
}
function testFunc(){
echo "blah";
return $this;
}
}
?>
精彩评论