PHP 5 introduced a way to write method declarations which has become somewhat en-vogue. You may have noticed the following syntax in a number of open source projects:
public function myFunction(SomeClass $instance)
This declaration forces the passed parameter to be an instance of
SomeClass, and is called type hinting.
The fact that PHP only supports single inheritance can be problematic since with such type hinting, you won't be able to use your own class implementation if it already inherits from another parent class.
A solution to this issue is to apply type hinting on interfaces instead, like the following:
public function myfunction(SomeInterface $instance)
Now your class only needs to implements the required interface and you are good to go. However, there's still a drawback. If you want to override a type hinted method, you won't be able to change the type hint definition, which limits the overriding capabilities. Worst since polymorphism (a.k.a overloading) is not available for PHP things generaly leads to a proliferation of method names for a same task (e.g.
stuffWithCollectionInterface()/stuffWithArray() instead of a unique
stuff() method). And since
array doesn't implement the
Traversable interface, using
array as a type hint is like type hinting using a class name instead of an interface.
But PHP is a dynamic language, so you can avoid all this issues by simply writing:
public function myfunction($instance)
Pretty confusing, right?
So what does that really mean?
The above example only demonstrates that instead of adding some flexibility to the code, type hinting:
- forces developers to create interfaces for almost everything to keep a correct level of interoperability with other developers
- limits overriding capabilities
- tends to complexify API by introducing a lot of irrevelant method names
The main point to understand here is that type hinting is not really a feature like traits (PHP 5.4) or generators (PHP 5.5) but more like a property of statically-typed languages. Since PHP is a dynamic language, using type hinting makes it less "dynamic". So, to 'neutralize' the type hinting issue, interfaces are mandatory almost everywhere.
Why do so many people use type hinting in PHP?
I've no clear answer to this question but I guess it's probably the result of some Java developpers influence who tends to code in PHP like they did in Java. In Java for example some Dependency Injection techniques are based on code introspection. So the "type hint" is used for being able to automatically inject some instances of the correct type in the called method. But the fact that a technique works for a statically typed languages doesn't means it's the best option for a dynamically typed language too.
Some people using type hinting often argue that it enhances the "degree of confidence that your code works" because a method will only accept parameters which respect a "contract". So type hinting somehow produces some "better" code with "fewer" bugs.
This reminds me of an old post, where the author eventually found that static type checking was redundant with TDD. Please take a moment to read it. Personally, I had a similar life experience on statically-based language so I couldn't agree more with the conclusions of the author.
In my opinion, if you really want to deal with bugs, you'll need to test your application. Type hinting is at the same time limited, inadequate and insufficient for testing an application. And although some claim that both tests & types are required, I can't concur since I'm developing using dynamic languages for the past 10 years and I only encountered type issues a couple of times during this whole period.
Does that mean statically typed languages are bad?
Not at all, Static & Dynamic languages are both valid paradigms but you can't just mix random concepts from both lands and expect to obtain a better paradigm. Dynamic languages helped me to write significantly easier & less cluttered code, and enhanced my productivity. Adding type hinting at this step doesn't make sense for me since it doesn't :
- exempt you from writing tests
- produce better performance (like static types did in statically typed languages)
- make your code easier to play with and share (it's quite the opposite)
In a follow-up post, we will talk about interfaces and why to use them (outside the scope of making type hinting more flexible, of course).