phplaravelobjectcontainerstyped

what does it mean by "typed objects"?


in the documentation of laravel for container service through this link:https://laravel.com/docs/7.x/container
below the title : "Binding Typed Variadics" you will find this : Occasionally you may have a class that receives an array of typed objects using a variadic constructor argument.

so what is typed object?

and subsequently what is untyped object?

code:

class Firewall
{
protected $logger;
protected $filters;

public function __construct(Logger $logger, Filter ...$filters)
{
    $this->logger = $logger;
    $this->filters = $filters;
}
}

Solution

  • Since PHP is an interpreted language you have a dynamic type system. That means, that for example a sinlge variable can hold values of multiple types:

    $foo = "Now I'm a string";
    $foo = 42; // And now I'm a number
    

    Now the question becomes where the "typed objects" fit in. In PHP Version 5 type declarations got introduced, because the dynamic type system imposes some problems. First and foremost you loose the ability to have static type checking.

    For example the following function can missbehave:

    
    function doSomething($a, $b)
    {
      // imagine costly and long running operation here...
      return $a + $b;
    }
    
    echo doSomething(1, 2);              // -> 3
    echo doSomething('hello ', 'world'); // -> Would result in an error, but only at runtime
    
    

    To counteract type hints where introduced which the PHP interpreter can use to reason about function parameters (and return types etc.). Additionally now that we've got types we can use a technique called reflection to introspect what the function or rather method expects to get passed into to provide the proper objects.

    So to go full circle and answer your question: A typed object simply means type hinting the method parameter so laravel's service container can infer what object you'd like to be injected into your method.

    // not using typed objects:
    class Firewall
    {
      protected $logger;
      protected $filters;
    
      public function __construct($logger, ...$filters)
      {
        $this->logger = $logger;
        $this->filters = $filters;
      }
    }
    
    // using typed objects:
    class Firewall
    {
      protected $logger;
      protected $filters;
    
      public function __construct(Logger $logger, Filter ...$filters)
      {
        $this->logger = $logger;
        $this->filters = $filters;
      }
    }
    

    Additional information: The reason you want to inject your dependencies rather than creating them inside your classes themselves is to obtain inversion of control, preferably by injecting interfaces so you get loose coupling on top.