0

Consider this simple class:

<?php declare(strict_types=1);

class Blog
{
    private $user;

    public function __construct(string $user)
    {       
        $this->user = $user;    
    }

    public function post ()
    {
        return 'New post by '.$this->user;      
    }
}

Using basic dependency injection works fine:

$blog = new Blog('Bob');
echo $blog->post();
// no errors, works as expected

$blog = new Blog(7);
echo $blog->post();
// fatal errors with TypeError, works as expected

But when using a dependency container like league\container the strict_types declaration is ignored?

$container = new League\Container\Container;
$container->add(Blog::class)->addArgument(7);
$foo = $container->get(Blog::class);
echo $foo->post();
// I passed `7` in the parameter, it doesn't work as expected
//  because it should've fatal error with TypeError because `7` is not a string

A quick view of the src folder of league\container reveals it's also using declare(strict_types=1); in all of its files. That said, I'm not sure if it's possible for the container to detect the parameter types of the class its initiating. If it's not possible then using declare(strict_types=1); is useless in this case?

IMB
  • 15,163
  • 19
  • 82
  • 140
  • 2
    The scope of the strict_types declaration is only the file it's in. See https://wiki.php.net/rfc/scalar_type_hints_v5#strict_types_declare_directive for details. And yes, reflection can be used to detect parameter types. – user3942918 Oct 22 '18 at 08:40
  • @PaulCrovella I see I guess that means `league\container` needs to refactor and put that functionality? – IMB Oct 22 '18 at 08:49
  • 1
    The container library uses Reflection. This is a known bug in PHP: https://stackoverflow.com/a/49140881/1461181 – odan Oct 22 '18 at 08:59
  • @DanielO I see. Do you recommend another DI container library that respects scalar type hints? – IMB Oct 22 '18 at 09:07
  • @DanielO That is not a bug at all. It's either a simple misunderstanding of the feature or a dislike of the design. – user3942918 Oct 22 '18 at 09:27
  • Afaik, all (PHP) DI libraries make use of reflection. Have you tried [PHP-DI](http://php-di.org/)? The (invalid) result should be the same. – odan Oct 22 '18 at 10:11
  • Adding some info to @user3942918's comment: the `declare` construct **affect the file that uses it and all child files**. I.e., if file `K.php` uses `declare` and includes file `C.php` and `D.php`, then `C.php` and `D.php` are affected by the *K*'s `declare`. And if file `A.php` includes file `K.php`, file `A.php` does **not** know about *K*'s `declare` constructor. – Wesley Gonçalves Apr 24 '20 at 21:09

0 Answers0