In PHP, can you instantiate an object and call a method on the same line?
PhpOopPhp Problem Overview
What I would like to do is something like this:
$method_result = new Obj()->method();
Instead of having to do:
$obj = new Obj();
$method_result = $obj->method();
The result doesn't actually matter to me in my specific case. But, is there a way to do this?
Php Solutions
Solution 1 - Php
The feature you have asked for is available from PHP 5.4. Here is the list of new features in PHP 5.4:
<http://php.net/manual/en/migration54.new-features.php>
And the relevant part from the new features list:
> Class member access on instantiation has been added, e.g. (new Foo)->bar().
Solution 2 - Php
You cannot do what you are asking ; but you can "cheat", using the fact that, in PHP, you can have a function that has the same name as a class ; those names won't conflict.
So, if you declared a class like this :
class Test {
public function __construct($param) {
$this->_var = $param;
}
public function myMethod() {
return $this->_var * 2;
}
protected $_var;
}
You can then declare a function that returns an instance of that class -- and has exactly the same name as the class :
function Test($param) {
return new Test($param);
}
And now, it becomes possible to use a one-liner, like you asked -- only thing is you are calling the function, thus not using new :
$a = Test(10)->myMethod();
var_dump($a);
And it works : here, I'm getting :
int 20
as output.
And, better, you can put some phpdoc on your function :
/**
* @return Test
*/
function Test($param) {
return new Test($param);
}
This way, you'll even have hints in your IDE -- at least, with Eclipse PDT 2.x ; see the screeshot :
http://extern.pascal-martin.fr/so/class-and-function.png">
Edit 2010-11-30 : Just for information, a new RFC has been submitted, a few days ago, that proposes to add this feature to one of the future versions of PHP.
See : Request for Comments: Instance and method call/property access
So, maybe doing things like these will be possible in PHP 5.4 or another future version :
(new foo())->bar()
(new $foo())->bar
(new $bar->y)->x
(new foo)[0]
Solution 3 - Php
You can do it more universally by defining an identity function:
function identity($x) {
return $x;
}
identity(new Obj)->method();
That way you don't need to define a function for each class.
Solution 4 - Php
How about:
$obj = new Obj(); $method_result = $obj->method(); // ?
:P
Solution 5 - Php
No, this is not possible.
You need to assign the instance to a variable before you can call any of it's methods.
If you really wan't to do this you could use a factory as ropstah suggests:
class ObjFactory{
public static function newObj(){
return new Obj();
}
}
ObjFactory::newObj()->method();
Solution 6 - Php
Simply we can do this
$method_result = (new Obj())->method();
Solution 7 - Php
You could use a static factory method to produce the object:
ObjectFactory::NewObj()->method();
Solution 8 - Php
I, too, was looking for a one-liner to accomplish this as part of a single expression for converting dates from one format to another. I like doing this in a single line of code because it is a single logical operation. So, this is a little cryptic, but it lets you instantiate and use a date object within a single line:
$newDateString = ($d = new DateTime('2011-08-30') ? $d->format('F d, Y') : '');
Another way to one-line the conversion of date strings from one format to another is to use a helper function to manage the OO parts of the code:
function convertDate($oldDateString,$newDateFormatString) {
$d = new DateTime($oldDateString);
return $d->format($newDateFormatString);
}
$myNewDate = convertDate($myOldDate,'F d, Y');
I think the object oriented approach is cool and necessary, but it can sometimes be tedious, requiring too many steps to accomplish simple operations.
Solution 9 - Php
I see this is quite old as questions go but here is something I think should be mentioned:
The special class method called "__call()" can be used to create new items inside of a class. You use it like this:
<?php
class test
{
function __call($func,$args)
{
echo "I am here - $func\n";
}
}
$a = new test();
$a->new( "My new class" );
?>
Output should be:
I am here - new
Thus, you can fool PHP into making a "new" command inside of your top level class (or any class really) and put your include command in to the __call() function to include the class that you have asked for. Of course, you would probably want to test $func to make sure it is a "new" command that was sent to the __call() command and (of course) you could have other commands also because of how __call() works.