PHP typehinting gotcha in exceptions/methods

July 13, 2011 – 5:23 pm Tags: ,

A small gotcha I recently ran into: If you use typehinting, PHP never checks that the class your typehint specifies actually exists!

Read more for some examples

As you may be aware of, typehints are quite convenient when you want a parameter to be an instance of some specific class or interface:

function sayHello(User $user) {
    echo 'Hello ' . $user->getName();
}

It turns out PHP never checks the class you use in the typehint…

function sayHello(Fasdfasdfasdfasd $user) {
    echo 'Hello ' . $user->getName();
}

This will actually work just fine, until you try to call it – but not because of the typehint, but because you can’t actually create a new instance of it as it doesn’t exist.

This same issue actually also applies to catch-blocks:

catch(ThisDoesNotNeedToExist $ex) { 
}

Worse with namespaces

This trap is a bit easier to fall into in namespaced code, due to the relative nature of namespace lookups in PHP:

namespace MyNamespace;
 
function something() {
    try {
        //Do something
    }
    catch(Exception $ex) {
        //catch something
    }
}

Notice the problem in above code?

If you didn’t, don’t worry – this is the most common error I see people make with namespaces.

The exception class actually being caught in the above code is MyNamespace\Exception. Of course, you would never get an error, because PHP doesn’t check the typehint. All exceptions are just going to fall through the catch-block just like it wasn’t there at all.

Is this really all bad?

In my opinion this is a rather poor “feature”, because one of the point of typehints in my opinion is to ensure validity of code and not checking the typehints does not really help in that at all.

However, while discussing this on #zftalk-community, user “Xerkus” suggested another point of view for the case with exceptions.

He mentioned that sometimes you may have a script which supports different types of libraries, each with their own exception types. If you only have one library installed, the code would fail to function if the exception class name was validated.

While he does have a kind of a valid point, I think it would be a better idea to use an adapter and wrap exceptions instead. It might be convenient in simple scripts that the class name isn’t validated, but I think overall it only causes more error-prone code.

Why does it work this way?

While I’m not really familiar with how PHP internally handles typehints, my best guess is that the typehint is simply converted into some kind of a string-check. This would explain why the class is never looked up.

If anyone has knowledge about this, please leave a comment.




So hey, another fun little gotcha that feels more like something they just forgot to consider :D

Further reading
For some discussion on wrapping exceptions, read exceptions and abstraction on this blog.

Share this:
  1. 11 Responses to “PHP typehinting gotcha in exceptions/methods”

  2. Not sure what you’re talking about. PHP 5.3:

    PHP Catchable fatal error: Argument 1 passed to wee() must be an instance of asdsad, instance of User given, called in /home/max/test.php on line 17 and defined in /home/max/test.php on line 12
    PHP Stack trace:
    PHP 1. {main}() /home/max/test.php:0
    PHP 2. wee() /home/max/test.php:17

    Code:

    class User {

    public $stuff;

    public function __construct($stuff) {
    $this->stuff = $stuf;
    }
    }

    function wee(asdsad $user) {
    echo $user->stuff;
    }

    $user = new User(‘asd’);
    wee($user);

    By mgribov on Jul 13, 2011

  3. The case was that just the typehint which is pointing to a class which does not exist will not cause an error. The effect is easier to see in the case with catch-blocks.

    By Jani Hartikainen on Jul 13, 2011

  4. That was just one quick example.

    Consider following situation:

    namespace MyNamespace;
    try{
    }
    catch(User\Acl\Exception $e) {
        //i want user to see 'no rights to do this' page
    }
    catch(SomeModel\Exception\RangeException $e) {
        //i want user to resubmit the data
    }
    catch(\Exception $e) {
        //catch any other exceptions
    }

    If user have no rights to do this, we will have \MyNamespace\User\Acl\Exception
    but \MyNamespace\SomeModel\Exception\RangeException was not used and not loaded. And vice versa.

    Check for class\interface existence will fail.

    As for adapter for libraries from my first example – language can’t rely on good practices.

    By xerkus on Jul 14, 2011

  5. Netbeans rarely lets me make namespace coding errors. The autocomplete just adds the “\” when it’s needed.

    Unless I’m missing something you’re suggesting PHP should have to autoload every typehint class?

    By Steve Clay on Jul 14, 2011

  6. @Xerkus thanks for the additional example :)

    @Steve Clay yes, that’s pretty much it… Although I suspect it may go a bit over the edge for dynamic languages like PHP.

    Additionally, Ryan Mauger mentioned on IRC that it could cause a lot of overhead from having to autoload some classes which weren’t necessarily even used, especially in case of larger frameworks.

    By Jani Hartikainen on Jul 14, 2011

  7. Hmmm, with PHP I personally would think the cost is higher for having strict checks. Typehinting in PHP is basically just that: a hint. It only makes sure that whatever you pass in actually is, extends or implements the class/interface you need it to.

    As for the try/catch example that is a slightly nasty gotcha, however with proper testing (which is fast and easy in a language like PHP) you’ll catch that fairly fast. Not to mention a lot of IDEs would probably catch it before that.

    By Fake51 on Jul 23, 2011

  8. that is a nice one :) i have never spotted that php does not check the existence of these classes :)

    cheers

    art

    By Ejsmont on Jul 30, 2011

  9. Wow, that is an absolutely horrific “gotcha”. Committed to memory! Thanks.

    By zofrex on Aug 11, 2011

  1. 3 Trackback(s)

  2. Jul 15, 2011: PHP typehinting gotcha in exceptions/methods | CodeUtopia – The … « Kokrajhar
  3. Jul 18, 2011: Jani Hartikainen Blog: PHP typehinting gotcha in Ausnahmen / Methoden | PHP Boutique
  4. Aug 29, 2013: Programowanie w PHP » Blog Archive » Jani Hartikainen’s Blog: PHP typehinting gotcha in exceptions/methods

Post a Comment

You can use some HTML (a, em, strong, etc.). If you want to post code, use <pre lang="PHP">code here</pre> (you can replace PHP with the language you are posting)