【问题标题】:PHP syntax to call methods on temporary objects调用临时对象方法的 PHP 语法
【发布时间】:2010-02-07 17:54:24
【问题描述】:

有没有办法在临时声明的对象上调用方法,而不必将第一个对象分配给变量?

见下文:

class Test
{
   private $i = 7;      
   public function get() {return $this->i;}   
}

$temp = new Test();
echo $temp->get(); //ok

echo new Test()->get(); //invalid syntax
echo {new Test()}->get(); //invalid syntax
echo ${new Test()}->get(); //invalid syntax

【问题讨论】:

    标签: php object oop temporary


    【解决方案1】:

    当我想要这种行为时,我使用以下解决方法。

    我声明了这个函数(在全局范围内):

    function take($that) { return $that; }
    

    那我这样用:

    echo take(new Test())->get();
    

    【讨论】:

      【解决方案2】:

      你能做的是

      class Test
      {
         private $i = 7;      
         public function get() {return $this->i;}
      
         public static function getNew() { return new self(); }
      }
      
      echo Test::getNew()->get();
      

      【讨论】:

      • 什么是 self() 函数?它在 PHP 中没有记录。你的意思是 { return new Test(); }
      • 这不是 self() 函数,它是创建 self 类的实例 - 我们所在的类。new self() 在这里是 new Test() 的同义词,还有额外的好处是不必更改它当您将 Test 类重命名为 OldTest ;-)
      • @Krelin:很酷,我以为 self 只是在类中调用静态变量/方法的关键字! :)
      【解决方案3】:

      为什么不这样做:

      class Test
      {
         private static $i = 7;      
         public static function get() {return self::$i;}   
      }
      
      $value = Test::get();
      

      【讨论】:

      • +1 因为在我看来这是唯一有意义的事情。虽然添加了 static 关键字
      • 我无能为力,但以这种方式使用课程总是让我感觉有点不舒服。感觉就像没有以正确的方式使用它们。另外,这可能不是 OP 想要的,因为该类的第二个实例可能需要为 $i 存储不同的值(以防他为了简洁而忽略了该部分)。
      • 对不起,但我真的不明白你的答案,但既然你得到了 3 票,我想知道我错过了什么。我不想要一个静态的 $i,而且你的类正在返回变量而不是对象。
      【解决方案4】:

      很遗憾,您不能这样做。恐怕PHP就是这样。

      【讨论】:

        【解决方案5】:

        没有。这是 PHP 解析器的一个限制。

        【讨论】:

          【解决方案6】:

          我经常使用这个方便的小功能

           function make($klass) {
              $_ = func_get_args();
              if(count($_) < 2)
                  return new $klass;
              $c = new ReflectionClass($klass);
              return $c->newInstanceArgs(array_slice($_, 1));
           }
          

          用法

          make('SomeCLass')->method();
          

          make('SomeClass', arg1, arg2)->foobar();
          

          【讨论】:

            【解决方案7】:

            不可能,为什么要以这种方式创建对象?

            对象的意义在于封装唯一的状态。在您给出的示例中,$i 将始终为 7,因此创建对象,然后从中获取 $i,然后将对象丢失给垃圾收集器,因为在 @ 之后没有对该对象的引用,这是没有意义的987654326@ 已返回。静态类,如其他地方所示,对此目的更有意义。或者关闭。

            相关话题:

            【讨论】:

            • @stereofrog 作为 Andi Gutmans 的 Zend Technologies 的创始人,我相信他知道他为什么这么说
            • @stereofrog 好吧,我不是核心社区的一员。我只是对 PHP 的内部工作没有足够的了解,因此我没有理由怀疑 Andi 的说法。而且我仍然看不到(new foo)-&gt;bar() 将如何增加静态方法或闭包的任何好处。
            • @stereofrog 被禁止!= 未介绍。这是一个显着的区别。就个人而言,我认为这种表示法没有任何附加价值。当然,它不那么冗长,但也不太可读。 $a = new Foo; $b = $a-&gt;bar(); $c = $b[25]; $c('blah'); 将实现同样的目标。在这方面,拥有它并没有使 PHP 变得更加完整。如果您想不惜一切代价提高可读性,您甚至可以使用class A { public function b($c) { return strtoupper($c); } } $a = array( create_function('', 'return new A;') ); echo $a[0]()-&gt;b('foo');
            • @Gordon Mine 只是一个简单的示例类,因为我希望问题的主题保留在可能的 PHP sintax 上。我知道没有可能的 sintax 来完成这项任务。仅供参考:动态创建对象的示例可能有用的是 Date 类。构造函数可以在不带参数调用时返回今天的日期,如果我想打印今天的日期,我可以这样做: echo "Today is:" 。新日期()->getAsDDMMYYYY(); //遗憾的是这是无效的sintax :)
            • @Marco 我仍然不相信这不应该在静态方法或闭包中。 Date 无论如何都不是一个很好的例子,因为您可以使用 date('dmy') 轻松实现这一点。
            【解决方案8】:

            这是一个老问题:我只是提供一个更新的答案。

            在所有受支持的 PHP 版本中(自 5.4.0 起,2012 年)您都可以这样做:

            (new Test())->get();
            

            参见https://secure.php.net/manual/en/migration54.new-features.php(“实例化时的类成员访问”)。

            【讨论】:

              【解决方案9】:

              这最近出现在 php-internals 上,不幸的是一些有影响力的人(例如狙击手)积极参与 PHP oppose the feature 的开发。发送电子邮件至 php-internals@lists.php.net,让他们知道您是一名成年程序员。

              【讨论】:

              • 一些遗留代码可能依赖于 2x2==5,所以你必须适应。
              猜你喜欢
              • 2014-06-26
              • 1970-01-01
              • 1970-01-01
              • 2014-09-28
              • 1970-01-01
              • 2015-07-20
              • 2012-07-15
              • 2017-11-11
              • 2020-01-19
              相关资源
              最近更新 更多