Categories


Archives


Recent Posts


Categories


PHP Primer: Type Hints

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

Today we’re going to give you a quick overview of PHP type hints. While the debate over how strongly PHP should be typed rages on, many PHP frameworks have started using type hints as metadata for implementing features like dependency injection. Whatever you think of strong typing or “magic” features like dependency injections, understanding type hints in the core PHP language is a de-facto responsibility for the modern PHP programmer.

The Problem

Let’s consider this simple PHP program.

<?php
#File: program.php
class Person
{
    public function getHelloMessage()
    {
        return 'Hello world!';
    }
}

function sayHello($object)
{
    echo $object->getHelloMessage(),"\n";
}

$person = new Person;
sayHello($person);

Nothing too complicated here, we

If we take a closer look at the sayHello function

function sayHello($object)
{
    echo $object->getHelloMessage(),"\n";
}

We see it accepts a single parameter, and then echos the output of that parameter’s getHelloMessage method. Run the program, and you’ll see the following output.

$ php program.php 
Hello world!

While simple, this program is not without its problems. Let’s say we change the sayHello function call

<?php
sayHello('Hola Mundo!');

If you run your program with the above function call, you’ll get the following error.

PHP Fatal error: Call to a member function getHelloMessage() on a non-object

That’s because we tried to pass this function a PHP string, when it expected an object. We’d have a similar problem if we passed the wrong sort of object to the function. The following call

sayHello((new stdClass));

Would spit out the following error message.

Fatal error: Call to undefined method stdClass::getHelloMessage()

If we know how to use our sayHello function, this isn’t a problem. However, other programmers who might want to use the sayHello function are left guessing as to what sort of variables its parameters accept. In our example this isn’t a real problem — the function is simple enough that a quick scan of its code tells us that $object needs to have a getHelloMessage method. However, for more complicated functions, not knowing what to pass in can be a real problem.

This is the problem type hints set out to solve.

The Solution

Type hints are pretty simple. Instead of writing a function like this

function sayHello($object)
{
    echo $object->getHelloMessage(),"\n";
}

We change the function prototype to include a “type” for each method parameter.

function sayHello(Hello $object)
{
    echo $object->getHelloMessage(),"\n";
}

In plain english, the above code says

The sayHello function accepts a single parameter named $object, and that object must be an object instantiated from the Hello class, or have Hello in its ancestry chain.

With the above sayHello function in place, if we tried running a program that passed in incorrect arguments

sayHello('Hola Mundo!');
sayHello((new stdClass));

We’d get different error messages

PHP Catchable fatal error: Argument 1 passed to sayHello() must be an instance of Person, instance of stdClass given

PHP Catchable fatal error: Argument 1 passed to sayHello() must be an instance of Person, string given

At first blush, this may make type hints seem useless — our program is still crashing with an error. If we look at bit deeper, there are a few benefits.

First, we get a better error message. PHP tells us which function argument is the problem

Argument 1 passed to sayHello

It also tells us what the problem was

must be an instance of Person, string given

In addition, passing an incorrect argument type is a different sort of PHP error, alluded to by the PHP error message.

PHP Catchable fatal error

Without the type hint, our program crashed with one of the following fatal errors

Call to a member function of a non-object
Call to undefined method

These are fatal, crashing, PHP errors that can’t be recovered from.

An argument not matching a type hint, however, raises a “less fatal” error. Specifically, a E_RECOVERABLE_ERROR error. While serious, this error can be recovered from in a custom error handler (set with set_error_handler).

Also, before we get on to the limitations of PHP’s type hinting system, we should point out that the word Catchable can throw some developers for a loop. Catchable here refers to the fact you can “catch” the error in a custom error handler, not that you can catch it in an actual try/catch block. PHP error handling is confusing and awful.

Limitations

So that’s a very brief overview of PHP’s type hinting system. As per usual, if you’re interested in learning more [the PHP manual](Today we’re going to give you a quick overview of PHP type hints is a great place to start.

If you work with Java of C# developers, you may wonder why they occasionally sneer (or stare blankly) at PHP’s type hinting system. Java and C# are compiled languages. That means a programmer’s workflow is to

These languages also require that every variable declaration include a type. Instead of saying

$foo = 27;

You need to say something like

Int $foo = 27;

These languages also require that you use types in your function parameters (i.e. PHP’s type hinting), and that each and every function have a return type set.

While this is a lot of extra work, and can turn off a lot of programmers just getting into the field, one benefit is the sort of errors we saw in our PHP program above can’t happen in these languages. The compiler refuses to compile a program with typing errors. This means those programs can never be run, and the programmer is forced the fix these errors before shipping.

Because PHP doesn’t have a compile step, and because the language will silently change a variable’s type for you behind the scenes, this sort of type safety is impossible in PHP, and for developers coming into PHP from these compiled languages, type hints can seem a little silly or weak.

Whether type hints are worth using is a question for each individual PHP team to decide on their own — but as we’ll see in my upcoming articles on Magento 2’s object system — many frameworks are using PHP type hints for things the core language never intended. You may not like PHP type hints, but they’re a part of the language and culture of PHP now, so make sure you know how they work.

Originally published July 3, 2015
Series Navigation<< Sellvana: Developer’s Alpha ReviewPHP Primer: Namespaces >>

Copyright © Alan Storm 1975 – 2017 All Rights Reserved

Originally Posted: 3rd July 2015