0

I'm learning my way into some more advanced programming with PHP.

I've seen that calling an non-existent method produces "call to undefined method" error.

PHP being quite flexible is there a technique that allows to intercept this error ? If so, how is this usually done ?

Edit: To clarify, I want to actually do something when the error occurs like send a reply back, not necessarily prevent it. Forget to mention that this is in the context of a class. Of course, methods only apply in the context of a class ;)

6
  • 1
    You might want to look at this, which also covers fatal errors: stackoverflow.com/a/2146171/1125956. You could have the error be logged in the shutdown function, and the user redirected to an error page, for example. Commented Aug 19, 2013 at 2:01
  • @SteAp It's not about preventing, it's about actually doing something when the error occurs. Say send a friendly message back to the caller to say what's happened. Could be useful in a framework. Commented Aug 19, 2013 at 3:07
  • @SteAp Just had a quick skim through the link. It starts off by is there any way that I can ignore functions.... Definitely not what I want. Will take note of answers though. Commented Aug 19, 2013 at 3:10
  • @Jack I actually want the class to handle this. Explanation given below. Commented Aug 19, 2013 at 3:37
  • Does an error actually kill the process ? I'm doing calls through ajax so it's simply messing up the response. Commented Aug 19, 2013 at 3:40

3 Answers 3

1

Yes, it's possible to trap calls to undefined methods of classes using magic methods:

You need to implement the __call() and/or __callStatic() methods as defined here.

Suppose you have a simple class CCalculationHelper with just a few methods:

class CCalculationHelper { static public function add( $op1, $op2 ) { assert( is_numeric( $op1 )); assert( is_numeric( $op2 )); return ( $op1 + $op2 ); } static public function diff( $op1, $op2 ) { assert( is_numeric( $op1 )); assert( is_numeric( $op2 )); return ( $op1 - $op2 ); } } 

At a later point of time, you need to enhance this class by multiplication or division. Instead of using two explicit methods, you might use a magic method, which implements both operations:

class CCalculationHelper { /** As of PHP 5.3.0 */ static public function __callStatic( $calledStaticMethodName, $arguments ) { assert( 2 == count( $arguments )); assert( is_numeric( $arguments[ 0 ] )); assert( is_numeric( $arguments[ 1 ] )); switch( $calledStaticMethodName ) { case 'mult': return $arguments[ 0 ] * $arguments[ 1 ]; break; case 'div': return $arguments[ 0 ] / $arguments[ 1 ]; break; } $msg = 'Sorry, static method "' . $calledStaticMethodName . '" not defined in class "' . __CLASS__ . '"'; throw new Exception( $msg, -1 ); } ... rest as before... } 

Call it like so:

 $result = CCalculationHelper::mult( 12, 15 ); 
Sign up to request clarification or add additional context in comments.

2 Comments

Right. So it would be possible to get the call and send a reply back ? Perhaps using some kind of callback pattern.
@JamesPoulson Yes, that's definitely possible. I've enhanced my answer.
1

Seeing how you don't wish to recover from these fatal errors, you can use a shutdown handler:

function on_shutdown() { if (($last_error = error_get_last()) { // uh oh, an error occurred, do last minute stuff } } register_shutdown_function('on_shutdown'); 

The function is called at the end of your script, regardless of whether an error occurred; a call to error_get_last() is made to determine that.

3 Comments

Can definitely use this. I realize my question may seem vague so to explain things I'd like an application to recover if a call goes through on a method that doesn't exist. Say for example a situation where the callee expects a JSON response. Can't have something an Exception and an error would also mess things up so, ideally, a standardized response could be sent to simply say, "inexistant method. Check application configuration.".
@JamesPoulson Then you could use inheritance and let the parent class take care of handling __call().
That's a good idea :) . Have a standard method à la template pattern in an abstract class or something. Yes, __call() does seem to fit here.
1

If you mean how to intercept non-existent method in a your custom class, you can do something like this

<?php class CustomObject { public function __call($name, $arguments) { echo "You are calling this function: " . $name . "(" . implode(', ', $arguments) . ")"; } } $obj = new CustomObject(); $obj->HelloWorld("I love you"); ?> 

Or if you want to intercept all the error

function error_handler($errno, $errstr, $errfile, $errline) { // handle error here. return true; } set_error_handler("error_handler"); 

1 Comment

Whoops. Did not mention I was on about classes so thanks for giving this a thought. Yes, the first possibility is along the lines of what I'm interested in. I suppose the error_handler is along the same lines as intercepting uncaught exceptions ? Don't think I could use that as intended.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.