1

I witnessed some strange behaviour regarding PHP's exception handling in a recent project. Case goes as follows.

In my app, I use namespaces. All classes are in individual source code files. The code relevant to this particular case, is spread over 3 classes.

The "outermost" class is a dispatcher (or router), which wraps the dispatch call inside a try-catch block. The dispatched request, calls a method in a third class, which runs code (wrapped in a try-catch block), which causes an exception.

Because I had omitted a use Exception; statement in the class where the error happens, the thrown exception trickles all the way back to the outermost layer (the dispatcher), where it is caught - causing me to scratch my head why the catch around the code causing the error isn't working.

To me this seems strange. Logically, PHP should in this situation (IMO) throw a Class not found exception/error, leading me to the actual error in my code, instead of trying to "stay alive" as long as possible.

Should this be filed as a bug, or is this expected behaviour?

Edit: Code example

File: class-a.php

<?php 
namespace hello\world;

class classA {
    protected $b;

    public function __construct() {
        $this->b = new \hello\world\classB();
    }

    public function doSomething() {
        try {
            $this->b->throwException();
        } catch (Exception $e) {

        }
    }
}

File: class-b.php

<?php 
namespace hello\world;

class classB
{
    public function throwException() {
        throw new \Exception("bar closed");
    }
}

File: run.php

<?php 
include 'class-a.php';
include 'class-b.php';

$a = new \hello\world\classA();

$a->doSomething();

ClassB throws an \Exception in ClassB::doSomething(), for which ClassA has a catch-clause, but because ClassA doesn't declare use Exception or catch (\Exception), the catch doesn't match and execution ends with a Uncaught exception error1. But in my opinion, it should cause a Class not found error.

I might be expecting too much of the permissive PHP compiler, but it would help in tracking down silly errors that should be easy for the compiler to spot.

1 If the $a->doSomething() in run.php was surrounded by a try..catch clause, the Exception would (or at least could) be caught there, since it trickles down the stack.

2
  • please attach a small code sample Commented Jul 12, 2011 at 6:25
  • 1
    Same described in comments: php.net/manual/en/language.exceptions.php#99702 Commented Jul 12, 2011 at 7:17

1 Answer 1

3

PHP's exception catching mechanism does not validate that the class you catch actually exists.

It exhibits the same behavior when using typehinting in functions, so I suspect it merely converts the exception/function type hint into a string or something and compares that with the type of the relevant object.

Whether this is a bug or not is questionable. Personally I think it should be classified as a bug, but PHP has all sorts of wonky behaviors :D

Sign up to request clarification or add additional context in comments.

8 Comments

Indeed, but with typehinting, I get the "class not found" error if I leave out the correct use in the class. Perhaps I would in this case, too, if I didn't have the "super-catch" lower in the stack. Got to do more research, maybe.
This is expected behavior. As those classes can be not loaded yet.
My suspicions were incorrect. Removing the "super-catch" does not result in a Class not found. Apparently, the throw construct gets special treatment. Go figure.
The reason throw new Foo causes a class not found is because you are actually trying to create a new instance of the class there. That differs somewhat from just having a type hint
@Xerxus argument makes sense to me.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.