Type hinting in PHP 7 - array of objects

后端 未结 7 1863
迷失自我
迷失自我 2020-12-08 03:36

Maybe I missed something but is there any option to define that function should have argument or return for example array of User objects?

Consider the following cod

7条回答
  •  感情败类
    2020-12-08 04:19

    I'm giving a generic answer about the type hinting of arrays in general.

    I made a variation of the selected answer. The main difference is that the parameter is an array instead of many instances of the checked class.

    /**
     * @param $_foos Foo[]
     */
    function doFoo(array $_foos)
    {return (function(Foo ...$_foos){
    
        // Do whatever you want with the $_foos array
    
    })(...$_foos);}
    

    It looks a bit fuzzy but it's pretty easy to understand. Instead of always unpacking the array at each call manually, the closure inside the function gets called with your array unpacked as the parameter.

    function doFoo(array $_foos)
    {
        return (function(Foo ...$_foos){ // Closure
    
        // Do whatever you want with the $_foos array
    
        })(...$_foos); //Main function's parameter $_foos unpacked
    }
    

    I find this pretty cool since you can use the function like any other language function having a ArrayOfType parameter. Plus, the error is handled the same way as the rest of PHP type hint errors. Furthermore, you are not confusing other programmers who will use your function and would have to unpack their array which always feels a bit hacky.

    You do need a bit of experience in programming to understand how this works. If you need more than one parameter you can always add them in the 'use' section of the closure.

    You can also use doc comments to expose the type hint.

    /**
     * @param $_foos Foo[] <- An array of type Foo
     */
    

    Here is an OO example:

    class Foo{}
    
    class NotFoo{}
    
    class Bar{
        /**
         * @param $_foos Foo[]
         */
        public function doFoo(array $_foos, $_param2)
        {return (function(Foo ...$_foos) use($_param2){
    
            return $_param2;
    
        })(...$_foos);}
    }
    
    $myBar = new Bar();
    $arrayOfFoo = array(new Foo(), new Foo(), new Foo());
    $notArrayOfFoo = array(new Foo(), new NotFoo(), new Foo());
    
    echo $myBar->doFoo($arrayOfFoo, 'Success');
    // Success
    
    echo $myBar->doFoo($notArrayOfFoo, 'Success');
    // Uncaught TypeError: Argument 2 passed to Bar::{closure}() must be an instance of Foo, instance of NotFoo given...
    

    Note: This also works with non-object types (int, string, etc.)

提交回复
热议问题