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

时间:2009-09-09 22:38:00

标签: php oop

我想做的是这样的事情:

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

而不是必须这样做:

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

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

9 个答案:

答案 0 :(得分:149)

您要求的功能可从PHP 5.4获得。以下是PHP 5.4中的新功能列表:

http://php.net/manual/en/migration54.new-features.php

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

  

已添加实例化的类成员访问权限,例如。 (新Foo) - > bar()。

答案 1 :(得分:37)

你不能做你所要求的;但你可以“欺骗”,因为在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;看到screeshot:



编辑2010-11-30:仅仅是为了获取信息,几天前提交了一个新的RFC,它建议将此功能添加到PHP的未来版本之一。

请参阅:征求意见:实例和方法调用/属性访问

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

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

答案 2 :(得分:19)

怎么样:

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

:P

答案 3 :(得分:18)

您可以通过定义身份函数来更普遍地实现:

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

identity(new Obj)->method();

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

答案 4 :(得分:15)

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

如果你真的不想这样做,你可以使用工厂作为ropstah建议:

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

答案 5 :(得分:6)

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

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

答案 6 :(得分:3)

我也在寻找一个单行代码来实现这一点,作为将日期从一种格式转换为另一种格式的单个表达式的一部分。我喜欢在一行代码中执行此操作,因为它是单个逻辑操作。所以,这有点神秘,但它允许您在一行中实例化和使用日期对象:

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

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

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

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

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

答案 7 :(得分:2)

我们可以做到

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

答案 8 :(得分:0)

我觉得问题已经很久了,但我认为应该提到这一点:

名为“__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在你的顶级类(或任何类)中创建一个“新”命令,并将你的include命令放入__call()函数中以包含你所要求的类。当然,您可能希望测试$ func以确保它是发送到__call()命令的“新”命令,并且(当然)由于__call()的工作原理,您也可以使用其他命令。 / p>