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.
    – James P.
    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.
    – James P.
    Commented Aug 19, 2013 at 3:10
  • @Jack I actually want the class to handle this. Explanation given below.
    – James P.
    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.
    – James P.
    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 );
2
  • Right. So it would be possible to get the call and send a reply back ? Perhaps using some kind of callback pattern.
    – James P.
    Commented Aug 19, 2013 at 3:11
  • 1
    @JamesPoulson Yes, that's definitely possible. I've enhanced my answer.
    – SteAp
    Commented Aug 19, 2013 at 13:49
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
  • 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.".
    – James P.
    Commented Aug 19, 2013 at 3:34
  • 1
    @JamesPoulson Then you could use inheritance and let the parent class take care of handling __call().
    – Ja͢ck
    Commented Aug 19, 2013 at 3:42
  • 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.
    – James P.
    Commented Aug 19, 2013 at 3:45
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
  • 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.
    – James P.
    Commented Aug 19, 2013 at 3:14

Not the answer you're looking for? Browse other questions tagged or ask your own question.