-1

Instead of just a normal PHP error, is it possible to throw an exception if a value is not passed to a method?

$obj=new foo();
$obj->bar(null); //This is okay
$obj->bar();     //This should throw an error

class foo {
   public function bar($value) {}
}
user1032531
  • 24,767
  • 68
  • 217
  • 387
  • 1
    Well you could check via [`func_num_args()`](http://www.php.net/manual/en/function.func-num-args.php), did you try/research anything already? – kero Jun 22 '14 at 13:20
  • @kingkero. I've tried setting the argument to a value (i.e. `public function bar($value=null)`, and then testing if it is set, but doesn't work when passing NULL. – user1032531 Jun 22 '14 at 13:22
  • @kingkero Wouldn't `func_num_args()` be located in `public function bar`, and thus the PHP error would occur before testing it? I want the class to be responsible to detect errors and throw exceptions, and not have the main script do so. – user1032531 Jun 22 '14 at 13:23
  • Sorry, overread the little word "instead". Could you elaborate on what you already tried/researched? Does [this answer](http://stackoverflow.com/questions/1241728/can-i-try-catch-a-warning) help? – kero Jun 22 '14 at 13:31
  • @kingkero Your latest post sheds some light. I was thinking of doing this, but only wish certain errors (i.e. not passing the value) to initiate an exception, and anything else to respond as normal and issue an error or warning. – user1032531 Jun 22 '14 at 13:36

2 Answers2

2

It seems to be not the best idea to handle missing arguments by ourselves (we have default values for that), but I was interested how could I achieve this. After looking for solutions here and there, I've came up with the following:

<?php

class foo {

    function warning_handler($errno, $errstr) {
        // just compare the strings because we don't have particular warning number
        if (strpos($errstr, 'Missing argument 1') === 0) {
            // throw exception or do whatever you want to handle this situation
            throw new Exception('Custom handler: First argument is missing');
        }
        // execute original error handler
        return false;
    }

    function __call($name, $arguments) {
        // if required, check whether method exists, before calling
        // if required, check whether particular method should be wrapped
        set_error_handler(array($this, 'warning_handler'), E_WARNING);
        call_user_func_array(array($this, $name), $arguments);
        restore_error_handler();
    }

    // should not be public, because "__call" will not work
    protected function bar($value) {
        // ...
    }
}

$obj = new foo();
try {
    // calling without arguments will throw custom exception
    $obj->bar();
} catch (Exception $e) {
    echo $e->getMessage();
}

Idea source: Can I try/catch a warning?

Community
  • 1
  • 1
Michael Radionov
  • 12,859
  • 1
  • 55
  • 72
0

Surely, when you code this

class foo {
   public function bar($value) {
       echo 'You called';
   }
}

$obj=new foo();
$obj->bar(null); //This is okay
$obj->bar();     //This should throw an error

The result will be this when you test it.

You called
Warning: Missing argument 1 for foo::bar(), called in D:\PHP_SOURCE\tst.php on line 12 and defined in D:\PHP_SOURCE\tst.php on line 4

So you know that you have done something wrong!

But if you want to physically test for the existance of the parameter, but NULL is a valid parameter, you cannot do this as '$obj->bar();' is equivalent to $obj->bar(null);.

So all you have to do is make the default value for the parameter be something that could never be passed in that parameter, like so

class foo {
   public function bar($value='The Impossible') {
       if ( $value == 'The Impossible' ) {
          throw new Exception('Holy Cow Batman, The Impossible just happened');
       }
       echo 'You called' . PHP_EOL;
   }
}


try {
    $obj=new foo();
    $obj->bar(null); //This is okay
    $obj->bar();     //This should throw an error
}
catch (Exception $e ) {
    echo $e->getMessage();
}

Which will throw the required exception.

You called
Holy Cow Batman, The Impossible just happened

Hence allowing you to catch and manage the situation if such a thing is actually possible.

RiggsFolly
  • 93,638
  • 21
  • 103
  • 149