代码之家  ›  专栏  ›  技术社区  ›  weotch

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

  •  108
  • weotch  · 技术社区  · 17 年前

    我想做的是这样的:

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

    而不是必须这样做:

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

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

    8 回复  |  直到 17 年前
        1
  •  183
  •   nameless Delian Krustev    8 年前

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

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

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

    已添加实例化时的类成员访问权限, e、 g.(新食品)——>bar()。

        2
  •  37
  •   Glorfindel Doug L.    7 年前

    你不能做你要求的事;但是你可以“作弊”,因为在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);
    }
    

    现在,可以像您所问的那样使用一行程序了——唯一的问题是您正在调用函数,因此没有使用新的:

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

    它起作用了:在这里,我得到:

    int 20
    


    更好的是,您可以在函数中添加一些phpdoc:

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

    这样,您甚至可以在IDE中得到提示——至少在EclipsePDT2.x中是这样;请参阅screeshot:



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

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

    因此,在PHP 5.4或其他未来版本中,可能会执行以下操作:

    (new foo())->bar()
    (new $foo())->bar
    (new $bar->y)->x
    (new foo)[0]
    
        3
  •  19
  •   Tom Pažourek    15 年前

    通过定义标识函数,您可以更普遍地执行此操作:

    function identity($x) {
        return $x;
    }
    
    identity(new Obj)->method();
    

        4
  •  19
  •   Madhawa Priyashantha    10 年前

    怎么样:

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

    :P

        5
  •  16
  •   Richard de Wit oden    9 年前


    您需要先将实例分配给变量,然后才能调用它的任何方法。

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

    class ObjFactory{
      public static function newObj(){
          return new Obj();
      }
    }
    ObjFactory::newObj()->method();
    
        6
  •  6
  •   Ropstah    17 年前

    ObjectFactory::NewObj()->method();
    
        7
  •  5
  •   vimuth    6 年前

    我们可以做到这一点

    $method_result = (new Obj())->method();
    
        8
  •  3
  •   CodeCavalier    15 年前

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

    $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');
    

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

        9
  •  0
  •   Mark Manning    10 年前

    我认为这是一个老生常谈的问题,但我认为有一点应该提到:

    名为“\uuuCall()”的特殊类方法可用于在类内创建新项。您可以这样使用它:

    <?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()的工作方式,您还可以使用其他命令。

    推荐文章