tags:

views:

91

answers:

6

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...

A: 

You can, it's called a constructor

class C
{
   function __construct() {}
}

$v = new C();

More in the php manual:

http://www.php.net/manual/en/language.oop5.decon.php

adam
I don't think that's what the question was about.And your code wont work. You define a class "C" but instantiate "V".
Techpriester
Thanks - i'll blame that on being a Monday morning! Bug fixed
adam
A: 

It's a bug in php parser. Write a petition on http://bugs.php.net and kindly ask them to fix this.

stereofrog
+3  A: 

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.

Techpriester
See the manual section for call_user_method for more about this.
Techpriester
Also PHP 6 will not have that?
xdevel2000
I don't know if this issue will be fixed in PHP6. Anyway it's still a long time until 6 comes out.
Techpriester
A: 

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;
    }
}

?>
pinaki
why a negative vote?? care to explain please?
pinaki
+3  A: 

Not possible. See


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();
Gordon
A: 

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...

JMTyler
unfortunately, this doesn't work. php is not c, c#, java, delphi etc.
stereofrog
Hm, odd. I really could have sworn I've done this sort of thing in PHP before. Oh well!
JMTyler
Not true. Based on an operator precedence table new an () are first executed. Also other languages works the same way. So in Java, C#, etc if you do new C().foo() all go fine!
xdevel2000