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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1402505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 02:25:54  来源:igfitidea点击:

In PHP, can you instantiate an object and call a method on the same line?

phpoop

提问by weotch

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?

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

回答by Delian Krustev

The feature you have asked for is available from PHP 5.4. Here is the list of new features in PHP 5.4:

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

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

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

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

回答by Pascal MARTIN

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.

你不能做你所要求的;但是您可以“欺骗”,因为在 PHP 中,您可以拥有一个与类同名的函数;这些名字不会冲突。

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 :

现在,就像您问的那样,可以使用单行代码-唯一的问题是您正在调用该函数,因此不使用 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 :


而且,更好的是,您可以在您的函数中放置一些 phpdoc:

/**
 * @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 :

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





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.

编辑 2010-11-30 :仅供参考,几天前提交了一个新的 RFC,建议将此功能添加到 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 :

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

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

回答by Tom Pa?ourek

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.

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

回答by Jeff

How about:

怎么样:

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

:P

:P

回答by Pim Jager

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:

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

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

回答by Ropstah

You could use a static factory method to produce the object:

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

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

回答by CodeCavalier

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:

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

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.

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

回答by Mark Manning

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:

称为“__call()”的特殊类方法可用于在类内创建新项目。你像这样使用它:

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

因此,您可以欺骗 PHP 在您的顶级类(或任何真正的类)中创建一个“新”命令,并将您的 include 命令放入 __call() 函数以包含您要求的类。当然,您可能想要测试 $func 以确保它是发送到 __call() 命令的“新”命令,并且(当然)由于 __call() 的工作方式,您还可以拥有其他命令。

回答by Aruna Perera

Simply we can do this

只需我们可以做到这一点

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