Return type hinting is great!
When I use my IDE and experiment with classes that I haven’t used before, I really love that it tells me what kind
of object a method returns to me. My IDE doesn’t use Artificial Intelligence to know that, it reads the PHP docblocks.
* @return $this
public function setBaseUrl($url)
$this->baseUrl = $url;
In this small post I’ll tell you about the
@return tag. Return tags tell you about what you can expect to get
returned from a function or method.
A return type can be a primitive type like
bool (ar the alias
int (or alias
resource. There is also the primitive type
void which indicates that the method will return nothing
(in PHP this will be equal to
null), but the PSR-5 draft
@return void may be omitted. No need to write something that is optional and unmistakeable, right? So I personally
One last primitive type is
object. If you’re going to return an object, better make all returned objects implement a
common interface and use that as type hint. Even if the interface is completely empty.
In the case of a mutable object you often find
@return $this to be used.
This indicates that the setter, or any other method that changes the state of the object, will return the exact same
instance as on which the previous method was invoked on. After a chain of invoked methods, the returned object is still
the same object as the original one.
This is different from immutable objects:
An immutable object never modifies itself but returns a new object instead.
When you’re dealing with Immutable objects, a different kind of return type is required.
will indicate that this method on the object of type
ImmutableFoo will return an object of type
ImmutableFoo but not the same.
@return self will remove the need to retype the class name, of FQCN, in every return tag.
Late static binding
Imagine an interface
ImmutableContainer with a method
public function add($key, callable $resolver);. Whenever the
method is called on an implementing container, the container is supposed to clone itself, add the binding to the new container,
and return that new instance. In that case this is what
add method should be documented like:
* @param string $key
* @param callable $resolver
* @return static
public function add($key, callable $resolver);
It says: whatever class is implementing this, it will return a new object of its own type. It’s consistent with
PHP’s Late Static Binding feature and interpreted that way by your IDE.
Mixing return types
@param docblock tag sometimes has a compound set of types it accepts. For example
@param int|DateTimeInterval $ttl.
This means the method accepts both an integer and a DateTimeInterval to define what TTL (Time To Live) value to use. As long the description
includes the unit of the TTL value when it’s an integer (eg: TTL in seconds), this is all fine.
But when it’s about a return value, I’m very strongly against using compound return types. You don’t want everyone who’s
using a given method to check the type of the returned value. When a method would either return a certain type of object or
null to denote a failed action, the method should probably throw some kind of exception instead.
It turns out there is a use case for compound return types!
— Barry vd. Heuvel (@barryvdh) August 24, 2015
In this case the method returns an array of objects (like
@return DateTime), and more specifically a Collection object that implements the
Traversable interfaces. This return tag,
@return Collection|DateTime, does leave room for the person using the method to handle the returned value in any way he/she wants. Thanks, Barry, for the suggestion!
When you really don’t have a clue what a method will return, the type hint should be
@return mixed. There are only a handful of places where this makes sense. One being a
make) method on an IoC container. Another use case I see is when values are retrieved from a data store, like from a Cache store, where all values are unserialized before being returned.
Native return types
Of course, when we’re all running on PHP 7 we can have proper return types!
Happy type hinting!