# Exceptions instead of Fatal Error when calling non existent method?

- Thread: https://externals.io/message/34288
- Original archive: https://news-web.php.net/php.internals/34288
- Started by thrthr@gmail.com on 2007-12-31T11:28:23+00:00
- Messages: 7
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #34288 — thrthr@gmail.com — 2007-12-31T11:28:23+00:00

URL: https://externals.io/message/34288#34288

Hi!

I've never posted on internal before, but I've been a long time reader
of it. I've been using PHP for a long time, I think it all started
back in 2000 sometime, anyway - this is hardly a place to put my
entire php biography up for show, so I'll jump right to the action.

Ever since PHP5 and the much improved object model (exceptions, and
what not) there has been one thing missing (at least for me) the whole
time. When you call a method (and function, but this doesn't really
matter from an OO perspective) on an object that does not exist, you
get a "Fatal error: Call to undefined method Foo::bar() in
C:\www\index.php on line 4".

What I would like to argue/request is that there should be a way to
get an exception thrown when you call a non existent method on an
object, since it's not possible to catch `E_ERROR` with a user defined
function using `set_error_handler()` I can't see anyway to accomplish
this in the current implementation?

Why do you want this? To allow for "true" duck typing (which I think
fits good into PHP's dynamic nature) without having the risk of your
application running into fatal errors and now having to use
if(method_exists($obj, $method)) on every call I want to make.

I've come up with a couple of suggestions on how this could be
implemented, but I'm not very good with the inner workings of php /
zend engine (I've read parts of Saras book, but that's about it) so I
don't know how hard (or easy) any of these suggestions would be to
implement:


a) Change the error raised when running into an unknown method call
into it's own type that is fatal if not caught by an user defined
error handler?

b) Change the error raised to `E_WARNING` 

c) Change the error raised to `E_RECOVERABLE_ERROR` which as far as I
can make out is possible to handle with a user defined error handler?

d) Make the engine throw an exception of a special type when an
unknown method is called, possibly provide an php.ini-setting so you
can toggle between the old (E_ERROR) and the new
(UnkownMethodException) to not break BC?


Thanks for reading my message, regards Fredrik.

---

## #34291 — thrthr@gmail.com — 2007-12-31T11:43:48+00:00

URL: https://externals.io/message/34288#34291

>What is wrong with __call() ?
>See:
>        http://www.php.net/manual/en/language.oop5.overloading.php

Hi!

Yes, I'm aware of call() but it's very slow. Also it's not feasible to have
*all* my classes extend a base class with the a call containing a throw
InvalidMethodException, and what if I need to use 3rd party libraries that
make use of call in some other way. __call()  is a hack, that, at best, work
50% of the time.

Regards, Fredrik.

---

## #34293 — Mikko Koppanen — 2007-12-31T11:58:44+00:00

URL: https://externals.io/message/34288#34293 · In reply to: #34291

> Yes, I'm aware of call() but it's very slow. Also it's not feasible to
> have
> *all* my classes extend a base class with the a call containing a throw
> InvalidMethodException, and what if I need to use 3rd party libraries that
> make use of call in some other way. __call()  is a hack, that, at best,
> work
> 50% of the time.
>


Calling methods without knowing that they exist sounds like a hack to me.
How about using abstract classes or interfaces?

-- 
Mikko Koppanen

---

## #34295 — thrthr@gmail.com — 2007-12-31T12:09:57+00:00

URL: https://externals.io/message/34288#34295 · In reply to: #34293

> 2007/12/31, Mikko Koppanen
> Calling methods without knowing that they exist sounds like a hack to me. How about using abstract classes or interfaces?

If you look at, for example, python - calling methods that don't
*know* exists is common practice, it's not a hack from my point of
view. It's just easier to ask forgiveness then permission, to quote
Hopper.

I never understood the direction PHP is heading with type hinting,
static binding (SPL-Types?), etc. While I don't directly oppose it I
don't see any reason for it. I just thought that adding some type of
ability to handle unknown method calls (without forcing *every* class
to implement __call() in a specific way) would be a nice way for those
of us that want to continue to use php as the dynamic, duck-typed
language we learned. Maybe it will fall on deaf ears, but I thought it
was worth a chance and at least propose it here on internals.

Regards, Fredrik.

---

## #34298 — thrthr@gmail.com — 2007-12-31T13:01:25+00:00

URL: https://externals.io/message/34288#34298

> There is no need to implement __call() in every class,.
> Just make sure their parent class implements it.
Yes, I'm well aware of that - but that doesn't really help when taking
into account 3rd party libraries or places where it's not possible
because you don't have control over the base class.

> Changing PHP's behavior in a backward-incompatible way that would affect
> everyone and *forcing everyone* to use exceptions seems to be really bad
> idea, especially taking into account that your problem can be easily solved
> without it.
In my original post I proposed several ways that would not be
backwards incompatible, and maybe I put the subject on the original
message wrong - the key here isn't really exceptions but the ability
to handle unknown method calls without taking the entire process down
with it. Anyway this will be my last post on the subject since I don't
want to spam the list and I think I've expressed all my opinions about
it clearly.

Regards, Fredrik.

---

## #34299 — Stefan Walk — 2007-12-31T13:27:41+00:00

URL: https://externals.io/message/34288#34299

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Monday 31 December 2007 13:48:52 Antony Dovgal wrote:
> Changing PHP's behavior in a backward-incompatible way that would affect
> everyone and *forcing everyone* to use exceptions seems to be really bad
> idea, especially taking into account that your problem can be easily solved
> without it.

What exactly is the backwards compatibility break here? Without the change, 
the code simply dies ... if you don't catch the exception, the code simply 
dies ... except you get a backtrace now and can handle the exception if you 
want to.

Regards,
Stefan
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFHeO5UpPjfcppEficRAng4AJ4v4G+PyT07cQTYupTgKFnOA130yQCeKWYy
E2tzkWAHOmIKDc/CZw7Dtjw=
=ArZH
-----END PGP SIGNATURE

---

## #34322 — Derick Rethans — 2008-01-03T08:54:11+00:00

URL: https://externals.io/message/34288#34322 · In reply to: #34288

> What I would like to argue/request is that there should be a way to
> get an exception thrown when you call a non existent method on an
> object, since it's not possible to catch `E_ERROR` with a user defined
> function using `set_error_handler()` I can't see anyway to accomplish
> this in the current implementation?

 `E_ERROR` should during normal runs of your program *never* be hit in the 
first place. If it is something critical that still can be handled, 
 `E_RECOVERABLE_ERROR` should be used inside PHP. If that is not the case, 
please let us now and we can address that.

As for the calling undefined methods, __call() is your friend.

regards,
Derick
