0

I have a class Person.

I want to add error handling into my script, so that say, the user enters an incorrect email address the script will tell them. Usually not a problem at all, but now I am using OO classes I am in unfamiliar territory.

So. I guess I want to know how to handle multiple exceptions. Or do I need to try each line of code one at a time and catch each line? This seems slightly excessive. Ideally I'd like to do the following:

try {
    $people[$new]->set_fullname($_POST['name']);
    $people[$new]->set_active(true);
    $people[$new]->set_add1(rEsc($_POST['add1']));
    $people[$new]->set_add2(rEsc($_POST['add2']));
    $people[$new]->set_add3(rEsc($_POST['add3']));
    $people[$new]->set_add4(rEsc($_POST['add4']));
    $people[$new]->set_postcode(rEsc($_POST['postcode']));
    $people[$new]->set_phone(rEsc($_POST['phone']));
    $people[$new]->set_email(rEsc($_POST['email']));
} catch {
      echo 'Caught exception: ',  $e->getMessage(), "\n";       
}

But in my error handling, How can I catch multiple errors? I'd like to push all the error messages into an array and display them each nicely in the webpage. As far as I can see on php.net it seems that I can only catch one error message at a time.

Do I really have to try {} catch {} each line of code?

Chud37
  • 4,278
  • 12
  • 50
  • 98
  • 1
    You might want to read this -> http://stackoverflow.com/questions/729379/why-not-use-exceptions-as-regular-flow-of-control – Crisp Mar 24 '13 at 17:03
  • Once an exception is thrown, execution will go immediately to the catch block, so you will only catch one error. – Bafsky Mar 24 '13 at 17:09
  • Dammnit, So that means this code block will be two or three times the size just to error handle! There's gotta be a better way! – Chud37 Mar 24 '13 at 17:23

4 Answers4

4

Imho this shouldn't throw exceptions in the first place. Simply loop through the fields and add the possible errors to some $errors array.

Users screwing up fields is not an exceptional case. I don't even think the user object should be able to validate an emailaddress. That seems to be like a responsibility of the Form.

Also am I wondering what that rEsc function is you are using. Not only are you using a global function which makes it virtually impossible to swap it out for some other function in the future (tight coupling), but also the name is chosen badly. Also do I fail to see why you would want to escape stuff in that place (I guess that is what the thing does). Only escape / sanitize data when you are using it. And I'm wondering for what you are escaping your data, because if it is for database input there are far better ways.

PeeHaa
  • 66,697
  • 53
  • 182
  • 254
  • I was waiting for someone to comment on that. Your right, it's simply a shortcut for mysql_real_escape_string, (I haven't moved to PDO yet, I know - I'm going to). And yes all the data will go into a database. So what way do you suggest is better? – Chud37 Mar 24 '13 at 18:02
  • Also I hadnt thought of it, but you're probably right, this type of code doesn't need to be thrown and caught. – Chud37 Mar 24 '13 at 18:02
  • @Chud37 regarding the escaping I would just use the raw data in use [prepared statements and bound parameters](http://stackoverflow.com/questions/60174/how-to-prevent-sql-injection-in-php). – PeeHaa Mar 24 '13 at 18:03
0
try {
    $people[$new]->set_fullname($_POST['name']);
    $people[$new]->set_active(true);
    $people[$new]->set_add1(rEsc($_POST['add1']));
    $people[$new]->set_add2(rEsc($_POST['add2']));
    $people[$new]->set_add3(rEsc($_POST['add3']));
    $people[$new]->set_add4(rEsc($_POST['add4']));
    $people[$new]->set_postcode(rEsc($_POST['postcode']));
    $people[$new]->set_phone(rEsc($_POST['phone']));
    $people[$new]->set_email(rEsc($_POST['email']));
} catch (Exception $e) {
      echo 'Caught exception: ',  $e->getMessage(), "\n";       
} catch (EmailFormatException $em) {
      echo 'Caught exception: '. $e->getMessage();
}

Just continue it like that

Anujan
  • 918
  • 1
  • 9
  • 19
0

Here's how I would design this:

  • Create a validate() method on the Person class that verifies every property and returns an array of strings that explain the errors to the user. If there are no errors, have the method return null.
  • Do not use exceptions at all. They are slow; they complicate code maintenance (and you're seeing the symptoms in the approach you've taken so far)
  • Remove the custom methods for setting properties of the Person object. PHP is not Java. Set the properties directly.

Putting this all together:

class Person {

    public $name;
    public $address1;
    public $address2;

    public function validate() { }

}

And then your code:

$obj = new Person();
$obj->name = "Bob";
$obj->address1 = "1 Elm St.";
$validationResult = $obj->validate();
if ( $validationResult != null) { // there were errors
    print_r($validationResult);
}
Alex Weinstein
  • 9,499
  • 8
  • 38
  • 58
-3

You can make a foreach statement that sets the data that needs validation with try/catch inside the loop in order to populate an array with the errors, like that:

$errors = [];
foreach (['field1', 'field2', ...] as $field) {
    try {
        $method = "set_{$field}";
        $people[$new]->$method(rEsc($_POST[$field]));
    } catch (Exception $e) {
        $errors[] = $e->getMessage();
    }
}
Vestimir Markov
  • 340
  • 1
  • 8