Stuart Brown
Stuart Brown

Reputation: 987

PHP Dependency Injection - Including Class name in constructor

I'm a newbie to OO but am reading around and trying to learn to do things the 'right' way. I've been reading up on dependency injection and can understand why it is a good thing, however I am not totally clear on the syntax.

For example looking at this Basic PHP Object Oriented Instantiation and Dependency Injection question on SO I replicate the exact same code (with the changes as the answer suggests) and then print out what the methods return:

    $author = new Author('Mickey', 'Mouse');
print $author->getFirstName();

$question = new Question('what day is it?', $author);
print $question->getQuestion(); 

However I'm not clear on the role the class name plays in:

    public function __construct($question, Author $author)
{
    $this->author = $author;
    $this->question = $question;
}

If I remove it from my code nothing breaks. Is it just a human readable thing so that other people can explicitly see that there is a dependency or does it play a role in actually making the code work?

Thanks for any help!

Upvotes: 3

Views: 1208

Answers (1)

Nic Wortel
Nic Wortel

Reputation: 11423

It's a type hint, which is a feature of PHP 5. If you type hint a parameter (by prepending the class name to it), you force that parameter to be an object of that type. (it does not have to be an instance of that exact class, it can also be an instance of a subclass)

A type doesn't even necessarily have to be a class: you can also typehint using an interface.

See this (slightly altered) example from PHP's documentation:

<?php
class MyClass
{
    /**
     * $fooBar must be an instance of FooBar (or a subclass of FooBar).
     */
    public function foo(FooBar $fooBar)
    {
        // because we know that we have an instance of FooBar, we can use it's method barFoo()
        $fooBar->barFoo();
    }
}

class FooBar
{
    public function barFoo()
    {
        // do something
    }
}

Because this enables you to force the type of a parameter, you can be sure that it has a certain interface. In case of the above example, you can safely use the barFoo() method, since $fooBar is an instance of FooBar (and thus has barFoo() defined).

You can also use typehinting to force that a parameter is an array:

public function foo(array $bars)
{
    foreach ($bars as $bar) {
        // do something
    }
}

As Wilt pointed out in a comment, PHP 7 also introduced scalar type declarations, which means that you can also enforce scalar types (such as string, bool, int, etc.)

Note that boolean and integer will not work, you will have to use the short versions (bool and int).

// not possible:
public function bar(string $myText, int $someNumber)
{

}

Upvotes: 5

Related Questions