【问题标题】:calling a method of an object at instance creation在实例创建时调用对象的方法
【发布时间】:2010-03-29 09:29:28
【问题描述】:

在 PHP 中为什么我不能这样做:

class C
{
   function foo() {}
}

new C()->foo();

但我必须这样做:

$v = new C();
$v->foo();

在所有语言中我都可以做到这一点......

【问题讨论】:

    标签: php object


    【解决方案1】:

    从 PHP 5.4 开始你可以做

    (new Foo)->bar();
    

    在此之前,这是不可能的。见

    但是你有一些选择

    难以置信的丑陋解决方案,我无法解释:

    end($_ = array(new C))->foo();
    

    无意义的序列化/反序列化只是为了能够链接

    unserialize(serialize(new C))->foo();
    

    使用反射同样毫无意义的方法

    call_user_func(array(new ReflectionClass('Utils'), 'C'))->foo();
    

    使用 Functions as a Factory 的方法更加理智:

    // global function
    function Factory($klass) { return new $klass; }
    Factory('C')->foo()
    
    // Lambda PHP < 5.3
    $Factory = create_function('$klass', 'return new $klass;');
    $Factory('C')->foo();
    
    // Lambda PHP > 5.3
    $Factory = function($klass) { return new $klass };
    $Factory('C')->foo();
    

    最理智的方法使用Factory Method Pattern 解决方案:

    class C { public static function create() { return new C; } }
    C::create()->foo();
    

    【讨论】:

      【解决方案2】:

      从 PHP 5.4 开始,您可以:(new Foo())-&gt;someMethod();

      【讨论】:

        【解决方案3】:

        在 PHP 中,您不能在新创建的对象上调用任意方法,例如 new Foo()-&gt;someMethod();

        对不起,就是这样。

        但你可以像这样构建一个工作:

        <?php
        class CustomConstructor
        {
          public static function customConstruct($methodName)
          {
            $obj = new static; //only available in PHP 5.3 or later
            call_user_method($methodName, $obj);
            return $obj;
          }
        }
        

        像这样扩展 CustomContructor:

        class YourClass extends CustomConstructor
        {
          public function someCoolMethod()
          {
            //cool stuff
          }
        }
        

        然后像这样实例化它们:

        $foo = YourClass::customConstruct('someCoolMethod');
        

        我还没有测试过,但是这个或类似的东西应该可以工作。

        更正:这仅适用于 PHP 5.3 及更高版本,因为需要后期静态绑定。

        【讨论】:

        • 有关此内容的更多信息,请参见 call_user_method 的手册部分。
        • PHP 6 也没有那个?
        • 我不知道这个问题是否会在 PHP6 中修复。无论如何,距离6出来还有很长的时间。
        【解决方案4】:

        你应该不能像这样执行代码

        new C()-&gt;foo();

        在其他语言中,至少只要该语言准确地遵循逻辑就不会。该对象不仅仅是使用C() 创建的,而是使用完整的new C() 创建的。因此,如果您包含另一对括号,则假设您应该能够执行该代码: (new C())-&gt;foo();

        (请注意:我没有测试过上述内容,我只是说它应该假设有效。)

        大多数语言(我遇到过的)都以相同的方式处理这种情况。 C、C#、Java、Delphi...

        【讨论】:

        • 不幸的是,这不起作用。 php 不是 c、c#、java、delphi 等。
        • 嗯,奇怪。我真的可以发誓我以前在 PHP 中做过这种事情。哦,好吧!
        • 不正确。基于运算符优先级表 new 一个 () 被首先执行。其他语言也以相同的方式工作。因此,在 Java、C# 等中,如果您执行 new C().foo() 一切正常!
        【解决方案5】:

        我试过了,成功了——

        <?php
        
        $obj = new test("testFunc");
        
        class test{
            function __construct($funcName){
                if(method_exists($this, $funcName)){
                    self::$funcName();
                }
            }
        
            function testFunc(){
                echo "blah";
                return $this;
            }
        }
        
        ?>
        

        【讨论】:

        • 这无法实现提问者通过问题想要的链接能力。您的实现还要求显式使用构造函数参数来调用链式函数,这不是构造函数应该做的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-19
        • 1970-01-01
        • 2018-08-07
        • 1970-01-01
        • 2014-01-17
        • 2023-03-04
        • 1970-01-01
        相关资源
        最近更新 更多