在 PHP 中,可以在同一行上实例化一个对象并调用一个方法吗?

我想做的事情是这样的:

$method_result = new Obj()->method();

而不是去做:

$obj = new Obj();
$method_result = $obj->method();

在我的具体情况下,结果对我来说并不重要。但是,有没有办法做到这一点呢?

67491 次浏览

不,这不可能。
在调用变量的任何方法之前,需要将实例赋给变量。

如果你真的不想这么做,你可以像罗普斯塔建议的那样,利用一家工厂:

class ObjFactory{
public static function newObj(){
return new Obj();
}
}
ObjFactory::newObj()->method();

可以使用静态工厂方法生成对象:

ObjectFactory::NewObj()->method();

这个怎么样:

$obj = new Obj(); $method_result = $obj->method(); // ?

校对: P

您不能做您要求的事情; 但是您可以“欺骗”,使用这样一个事实: 在 PHP 中,您可以拥有一个与类同名的函数; 这些名称不会冲突。

所以,如果你声明一个类,像这样:

class Test {
public function __construct($param) {
$this->_var = $param;
}
public function myMethod() {
return $this->_var * 2;
}
protected $_var;
}

然后,您可以声明一个函数,该函数返回该类的一个实例——并且具有与该类完全相同的名称:

function Test($param) {
return new Test($param);
}

现在,可以像您要求的那样使用一行程序了——唯一的问题是您正在调用函数,因此不使用 new:

$a = Test(10)->myMethod();
var_dump($a);

而且很有效,在这里,我得到了:

int 20

作为输出。


而且,更好的是,你可以在你的功能中加入一些 phpdoc:

/**
* @return Test
*/
function Test($param) {
return new Test($param);
}

这样,您甚至可以在 IDE 中获得提示——至少在 Eclipse PDT 2.x 中是这样; 请参见截图:



编辑2010-11-30: 仅供参考,几天前提交了一个新的 RFC,提议将这个特性添加到 PHP 的未来版本中。

请参阅: < strong > Request for Comments: Instance and method call/property access

因此,在 PHP 5.4或其他未来版本中,也许可以做到这些:

(new foo())->bar()
(new $foo())->bar
(new $bar->y)->x
(new foo)[0]

你可以通过定义一个身份函数来实现:

function identity($x) {
return $x;
}


identity(new Obj)->method();

这样就不需要为每个类定义函数。

我也正在寻找一行程序来完成这项工作,作为将日期从一种格式转换为另一种格式的单个表达式的一部分。我喜欢用一行代码做这件事,因为这是一个单一的逻辑操作。因此,这有点神秘,但它允许您在一行内实例化并使用 date 对象:

$newDateString = ($d = new DateTime('2011-08-30') ? $d->format('F d, Y') : '');

将日期字符串从一种格式转换为另一种格式的另一种方法是使用 helper 函数来管理代码的 OO 部分:

function convertDate($oldDateString,$newDateFormatString) {
$d = new DateTime($oldDateString);
return $d->format($newDateFormatString);
}


$myNewDate = convertDate($myOldDate,'F d, Y');

我认为面向对象的方法是很酷和必要的,但是它有时可能是乏味的,需要太多的步骤来完成简单的操作。

您要求的特性可以从 PHP 5.4中获得。下面是 PHP 5.4的一些新特性:

Https://php-legacy-docs.zend.com/manual/php5/en/migration54.new-features

以及新功能列表中的相关部分:

已经添加了对实例化的类成员访问,例如 (new Foo)->bar().

我知道这个问题已经很古老了,但我认为有些事情应该提一下:

称为“ _ _ call ()”的特殊类方法可用于在类中创建新项。你可以这样使用:

<?php
class test
{


function __call($func,$args)
{
echo "I am here - $func\n";
}


}


$a = new test();
$a->new( "My new class" );
?>

产出应为:

I am here - new

因此,您可以欺骗 PHP 在顶级类(或任何类)中创建一个“ new”命令,并将 include 命令放到 _ _ call ()函数中以包含您要求的类。当然,您可能希望测试 $func,以确保它是发送给 _ _ call ()命令的“ new”命令,并且(当然)由于 _ _ call ()的工作方式,您还可以使用其他命令。

只要我们能做到

$method_result = (new Obj())->method();