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

前端 未结 9 1733
没有蜡笔的小新
没有蜡笔的小新 2020-11-27 14:01

What I would like to do is something like this:

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

Instead of having to do:

$obj = ne         


        
相关标签:
9条回答
  • 2020-11-27 14:09

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

    ObjectFactory::NewObj()->method();
    
    0 讨论(0)
  • 2020-11-27 14:15

    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.

    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 :

    $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 :

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



    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.

    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 :

    (new foo())->bar()
    (new $foo())->bar
    (new $bar->y)->x
    (new foo)[0]
    
    0 讨论(0)
  • 2020-11-27 14:22

    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:

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

    0 讨论(0)
  • 2020-11-27 14:23

    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.

    0 讨论(0)
  • 2020-11-27 14:26

    How about:

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

    :P

    0 讨论(0)
  • 2020-11-27 14:29

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

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

    0 讨论(0)
提交回复
热议问题