views:

162

answers:

9

Is there a way to call a method on a temporary declared object without being forced to assign 1st the object to a variable?

See below:

class Test
{
   private $i = 7;      
   public function get() {return $this->i;}   
}

$temp = new Test();
echo $temp->get(); //ok

echo new Test()->get(); //invalid syntax
echo {new Test()}->get(); //invalid syntax
echo ${new Test()}->get(); //invalid syntax
+3  A: 

Unfortunately, you can't do that. It's just the way PHP is, I'm afraid.

karim79
+1  A: 

Impossible and why would you create an object this way at all?

The point of an object is to encapsulate unique state. In the example you gave, $i will always be 7, so there is no point in creating the object, then getting $i from it and then losing the object to the Garbage collector because there is no reference to the object after $i was returned. A static class, like shown elsewhere, makes much more sense for this purpose. Or a closure.

Related topic:

Gordon
there are many cases when temporary objects are justified. It's really a shame that still haven't got a proper parser for php (since 6 years!). "A lot of thought", huh?
stereofrog
@stereofrog As Andi Gutmans' a founder of Zend Technologies, I trust him to know why he's saying that
Gordon
yes, this is exactly the problem in php core community - too much attention to ranks and merits instead of focusing on technical discussion.
stereofrog
@stereofrog Well, I'm not part of the core community. I just don't have sufficient insight into PHP's inner workings to have reason to doubt Andi's statement. And I still fail to see how `(new foo)->bar()` would be adding any benefit over a static method or a closure.
Gordon
the point is that a syntactically complete language should allow an expression (of any form) everywhere where a variable is allowed. There is no single reason to ban things like "(new foo)->bar()[25](blah)" from the language, just for the sake of logic and completeness.
stereofrog
@stereofrog banned != not introduced. That's a notable difference. Personally, I don't see any added value in this notation. Sure, it's less verbose, but it is also less readable. `$a = new Foo; $b = $a->bar(); $c = $b[25]; $c('blah');` will achieve the same thing. In this regard, it doesn't make PHP any more complete to have it. You can even do `class A { public function b($c) { return strtoupper($c); } } $a = array( create_function('', 'return new A;') ); echo $a[0]()->b('foo');` if you want to screw up readability at all cost.
Gordon
@Gordon Mine was just a simple example class because I wanted the subject of the question to remain on a possible PHP sintax.I understood there is no possible sintax to accomplish this task.FYI: an example were creating object on the fly could be useful is a Date class. Constructor could return today date when called with no parameters, if I want to print the today date, I could do:echo "Today is: " . new Date()->getAsDDMMYYYY(); //sadly this is invalid sintax :)
Marco Demajo
@Marco I'm still not convinced this shouldn't be in a static method or closure then. Date is not a good example anyway, because you can achieve this easily with `date('dmy')`.
Gordon
@Gordon: in C++ you can create temporary object, (I think also in Java), therefor I'm pretty sure they are useful at some point. Now I can't come up with a better idea than Date.
Marco Demajo
@Marco well, PHP is not C++ or Java. Whether you take this as an argument pro or contra PHP is up to you. As you can see by the comments below my answer and the linked mailing list archives, the opinions on the usefulness of temporary objects differ :)
Gordon
+3  A: 

No. This is a limitation in PHP's parser.

Ignacio Vazquez-Abrams
+6  A: 

What you can do is

class Test
{
   private $i = 7;      
   public function get() {return $this->i;}

   public static function getNew() { return new self(); }
}

echo Test::getNew()->get();
Michael Krelin - hacker
What's self() function? It's undocumented in PHP. Did u mean { return new Test(); }
Marco Demajo
It's not self() function, it's creating of instance of self class - the class we're in. `new self()` is synonymous to `new Test()` here, with additional bonus of not having to change it when you rename Test class to OldTest ;-)
Michael Krelin - hacker
@Krelin: cool, I thought self was only a keyword to call static vars/methods inside class! :)
Marco Demajo
+4  A: 

Why not just do this:

class Test
{
   private static $i = 7;      
   public static function get() {return self::$i;}   
}

$value = Test::get();
Chacha102
+1 because it's the only thing that makes sense in my opinion. Added `static` keyword though
Gordon
I cannot help it, but using classes this way always makes me feel a bit uncomfortable. It feels like using them not in a proper way. Plus, this may not be what the OP wanted, since a second instance of the class may need to store a different value for $i (in case he left that part out for brevity).
Cassy
@Chacha102: sorry, but i really don't understand your answer, but since you got 3 votes up I wonder what I'm missing. I don't want a static $i, moreover you class is returing the variable and not the object.
Marco Demajo
A: 

You'd probably be interested in the manual page for the static keyword.

Dolph
+1  A: 

i often use this handy little function

 function make($klass) {
    $_ = func_get_args();
    if(count($_) < 2)
        return new $klass;
    $c = new ReflectionClass($klass);
    return $c->newInstanceArgs(array_slice($_, 1));
 }

usage

make('SomeCLass')->method();

or

make('SomeClass', arg1, arg2)->foobar();
stereofrog
+1 clever stuff. A bit complex.
Marco Demajo
+1  A: 

This has come up very recently on php-internals, and unfortunately some influential people (e. g. sniper) active in development of PHP oppose the feature. Drop an email to [email protected], let them know you're a grownup programmer.

just somebody
funny how they're "discussing" something that is clearly a bug... like "our engine returns 5 for 2x2, let's discuss if this is worth fixing" ))
stereofrog
Some legacy code might rely on 2x2==5, so you have to be accommodating.
Alex JL
+6  A: 

I use the following workaround when I want to have this behaviour.

I declare this function (in the global scope) :

function take($that) { return $that; }

Then I use it this way :

echo take(new Test())->get();
ratibus
very nice... ))
stereofrog
that is clever.
karim79