Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 1 of 2 12 LastLast
Results 1 to 15 of 24
  1. #1
    Regular Coder
    Join Date
    Oct 2010
    Location
    Florence, MS
    Posts
    484
    Thanks
    10
    Thanked 33 Times in 32 Posts

    Handling errors in my Validation class

    Ok, so I've built this pretty simple validation class for forms.
    Here is code:
    PHP Code:

    class FormValidation {
        
        
    // public properties
        
    public $errors;
        
        
    // private properties
        
        
    private $isValid true;
        
        function 
    __construct($fields) {
            
    $this->getRules($fields);
            if(!
    $this->isValid) {
            return 
    $this->errors;    
            }
        }
        
        private function 
    isEmpty ($field) {
              if (!isset(
    $_POST["{$field}"]) || empty($_POST["{$field}"])) {
                    return 
    $this->errors["{$field}"] ="* "ucfirst($field) . " cannot be empty.";
              } 
        }
        private function 
    getRules($fields) {
            foreach (
    $fields as $field=>$rules) {
               if(
    array_key_exists($field$_POST)){
                    foreach (
    $rules as $rule) {
                        if(
    method_exists($this,$rule)) {
                            
    $this->$rule($field);    
                        }else {
                            return 
    $this->errors["method"] = "This rule does not exist";    
                        }
                    }
               } else {
                     return    
    $this->errors["exist"] = "This field does not exist"
               }
            }
        }
        

        private function 
    checkUsername($username) {
            
    $username_regex '/[^a-zA-Z0-9_-]/';
            if ((
    strlen($username) < 6) || (strlen($username) > 32)) {
                return 
    $this->errors["username"] = "* Your username must be greater than 6 characters and less than 32 characters.";    
            } else if (!
    preg_match($username_regex$username)) {
                return 
    $this->errors["username"] = "* Your username can only consist of lowercase and uppercase letters, any numbers between 0-9, _, or - .";
            } else {
                    
    $users User::find_by_username($username);
                    if (!empty(
    $user)) {
                        return 
    $this->errors["username"] = "* The username you selected has already been taken. Please select another.";
                    }
            }
        }

        private function 
    checkErrors() {
            if(!empty(
    $this->errors)) {
                
    $this->isValid false;    
            }
        }
        
        

    I call the class like this:
    PHP Code:
    $fields = array(
        
    'username' => 
                        array(
    "isEmpty""checkUsername"), 
        );
        
    $validation = new FormValidation($fields); 
    It appears to work, when I submit the field in without anything in it. Yet, it doesn't output the first error of checkUsername. It just says "* Your username can only consist of lowercase and uppercase letters, any numbers between 0-9, _, or - ." It doesn't even out put that the field cannot be empty. Any ideas how to handle my errors in the class better??
    Notice: If you post a problem and it gets fixed, please remember to go back and place it as solved. ;)
    I always recommend the HEAD First series of books for learning a new coding language. ^_^

  • #2
    12k
    12k is offline
    New Coder
    Join Date
    Jan 2012
    Posts
    29
    Thanks
    0
    Thanked 6 Times in 6 Posts
    In order to display more then one error at once, you will have to store the errors into an array, and use several if statements rather then if/else if/else. After the error array is set, you can then check to see if the error array is empty to know whether to proceed or not.

  • #3
    Regular Coder
    Join Date
    Oct 2010
    Location
    Florence, MS
    Posts
    484
    Thanks
    10
    Thanked 33 Times in 32 Posts
    I think I get what you are going at. Mind showing me an example? I tried it on my side and I have something working but I wanna see what you come up with as opposed to what I wrote.
    Notice: If you post a problem and it gets fixed, please remember to go back and place it as solved. ;)
    I always recommend the HEAD First series of books for learning a new coding language. ^_^

  • #4
    12k
    12k is offline
    New Coder
    Join Date
    Jan 2012
    Posts
    29
    Thanks
    0
    Thanked 6 Times in 6 Posts
    How its currently working, its set to

    Do This:
    Or Do This:
    Else do this:

    So only one is being called.

    You would have to do something like this:

    PHP Code:

    private function AddError($errorType$errorMessage)
    {
            
    $pos count($this->errors[$errorType]);
            
    $this->errors[$errorType] = $errorMessage;
    }


        private function 
    checkUsername($username) { 
            
    $username_regex '/[^a-zA-Z0-9_-]/'
            if ((
    strlen($username) < 6) || (strlen($username) > 32)) { 
                
    $this->AddError("username""* Your username must be greater than 6 characters and less than 32 characters.");
            }
            if (!
    preg_match($username_regex$username)) { 
                
    $this->AddError("username""* Your username can only consist of lowercase and uppercase letters, any numbers between 0-9, _, or - .");
            }
            
    $users User::find_by_username($username); 
            if (!empty(
    $user)) { 
                
    $this->AddError("username""* The username you selected has already been taken. Please select another.");
            } 
        } 
    Then check to see if count($this->errors['username']) == 0 before you continue.

  • #5
    Regular Coder
    Join Date
    Oct 2010
    Location
    Florence, MS
    Posts
    484
    Thanks
    10
    Thanked 33 Times in 32 Posts
    Yeah, I thought you meant something like that. I tried to incorporate what you had into mine but it didn't work. Hmm, I'll have to think about this even more than I thought.
    Notice: If you post a problem and it gets fixed, please remember to go back and place it as solved. ;)
    I always recommend the HEAD First series of books for learning a new coding language. ^_^

  • #6
    12k
    12k is offline
    New Coder
    Join Date
    Jan 2012
    Posts
    29
    Thanks
    0
    Thanked 6 Times in 6 Posts
    If you want feel free to add me to msn @ twelve_k@live.com and I can help you out with it.

  • #7
    Regular Coder
    Join Date
    Oct 2010
    Location
    Florence, MS
    Posts
    484
    Thanks
    10
    Thanked 33 Times in 32 Posts
    Ok, so I'm going to try to explain what I want it to be doing. I want to be able to list the fields of a form inside and array and inside that array I want to be able to list the rules for each field.
    PHP Code:
    $fields = array( 
        
    'username' =>  
                        array(
    "isEmpty""checkUsername"),  
        ); 
    When I call my class, the method getRules is called and what this does is takes the rules array inside the fields array and check to see if that content is a method of the class, if it is it will then call the rule and place the field inside of it to run.

    I want it to be able to run the first method called and if no errors occur then to run the second method. In this case, I want it to be able to run the isEmpty method, then if no errors occurs, it runs the checkUsername method. Inside the username method, I want it to first check the length. If it is less or more than the fixed lengths then it needs to place an error in the error array. If there isn't an error for that first part of the username function, I want it to then check the characters to see if they are in compliance and do the exact same as the first part of the function if there is an error. Finally, if there is no error for that second part of the username function, it then checks to see if the username is taken of not then no errors occured. If it is taken, then an error needs to be placed.
    Notice: If you post a problem and it gets fixed, please remember to go back and place it as solved. ;)
    I always recommend the HEAD First series of books for learning a new coding language. ^_^

  • #8
    Senior Coder
    Join Date
    Jul 2011
    Posts
    1,226
    Thanks
    3
    Thanked 171 Times in 171 Posts
    Quote Originally Posted by Chris Hick View Post
    Ok, so I'm going to try to explain what I want it to be doing. I want to be able to list the fields of a form inside and array and inside that array I want to be able to list the rules for each field.
    PHP Code:
    $fields = array( 
        
    'username' =>  
                        array(
    "isEmpty""checkUsername"),  
        ); 
    When I call my class, the method getRules is called and what this does is takes the rules array inside the fields array and check to see if that content is a method of the class, if it is it will then call the rule and place the field inside of it to run.

    I want it to be able to run the first method called and if no errors occur then to run the second method. In this case, I want it to be able to run the isEmpty method, then if no errors occurs, it runs the checkUsername method. Inside the username method, I want it to first check the length. If it is less or more than the fixed lengths then it needs to place an error in the error array. If there isn't an error for that first part of the username function, I want it to then check the characters to see if they are in compliance and do the exact same as the first part of the function if there is an error. Finally, if there is no error for that second part of the username function, it then checks to see if the username is taken of not then no errors occured. If it is taken, then an error needs to be placed.
    There's a few ways you can do this. The way I would do it, is have a foreach on your $_POST (I assume it's POST) then check for array_key_exists(). Then, if it does, foreach that field to get the rules, then have a switch to bucket the different rules into methods. Something like this:
    PHP Code:
    foreach($_POST as $key=>$value){
        if(
    array_key_exists($key,$this->fields)){
            foreach(
    $this->fields as $rule){
                try{
                    
    // Pretty sure you can do this, where $rule is a method name inside the class
                    
    $this->$rule($value);
                catch(
    Exception $e){
                    echo 
    '<br/>Exception: '.$e->getMessage();
                }
            }
        }
        else{
            
    // No rule!
        
    }

    This will spit out an exception every time a rule failes. Although, in your rule, you will have to throw a new exception when you find an error.
    Useful function to retrieve difference in times
    The best PHP resource
    A good PHP FAQ
    PLEASE remember to wrap your code in [PHP] tags.
    PHP Code:
    // Replace this
    if(isset($_POST['submitButton']))
    // With this
    if(!empty($_POST))
    // Then check for values/forms. Some IE versions don't send the submit button 
    Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.

  • #9
    Regular Coder
    Join Date
    Oct 2010
    Location
    Florence, MS
    Posts
    484
    Thanks
    10
    Thanked 33 Times in 32 Posts
    Panther, that is a good suggestion. Certainly do able. But it will not help me with the way I want to return the errors. On my page, I have something like this beside each form input.
    PHP Code:
    if(isset($validation->errors['username'])) { echo $validation->errors['username'];}
    // substituting username for the name of that input field 
    Notice: If you post a problem and it gets fixed, please remember to go back and place it as solved. ;)
    I always recommend the HEAD First series of books for learning a new coding language. ^_^

  • #10
    Senior Coder
    Join Date
    Jul 2009
    Location
    South Yorkshire, England
    Posts
    2,318
    Thanks
    6
    Thanked 304 Times in 303 Posts
    Quote Originally Posted by Chris Hick View Post
    Panther, that is a good suggestion. Certainly do able. But it will not help me with the way I want to return the errors. On my page, I have something like this beside each form input.
    PHP Code:
    if(isset($validation->errors['username'])) { echo $validation->errors['username'];}
    // substituting username for the name of that input field 
    You're assigning all errors to an array and merely want to print those errors if any exist?

  • #11
    Regular Coder
    Join Date
    Oct 2010
    Location
    Florence, MS
    Posts
    484
    Thanks
    10
    Thanked 33 Times in 32 Posts
    MattF, in a nutshell, yes. I want each error to have the key of its fieldname.
    Notice: If you post a problem and it gets fixed, please remember to go back and place it as solved. ;)
    I always recommend the HEAD First series of books for learning a new coding language. ^_^

  • #12
    Senior Coder
    Join Date
    Jul 2009
    Location
    South Yorkshire, England
    Posts
    2,318
    Thanks
    6
    Thanked 304 Times in 303 Posts
    If you're just wanting to show all errors once you've processed the form, do something along the lines of:

    Code:
    if (!empty($validation->errors))
    {
        foreach ($validation->errors as $key => $error)
        {
            print($key.': '.$error."\n");
        }
    }
    else
    {
        #All inputs correct.
    }

    p.s: I've only skimmed this thread, so may have missed reference to specifics of what you're trying to achieve. Apologies if so.

  • #13
    Regular Coder
    Join Date
    Oct 2010
    Location
    Florence, MS
    Posts
    484
    Thanks
    10
    Thanked 33 Times in 32 Posts
    MattF, I notice a lot of sites do the method you mentioned above, but for personal reasons I don't like that idea. I like the idea of stating the field specific errors next to the field. Instead of all in one area.
    Notice: If you post a problem and it gets fixed, please remember to go back and place it as solved. ;)
    I always recommend the HEAD First series of books for learning a new coding language. ^_^

  • #14
    Senior Coder
    Join Date
    Jul 2009
    Location
    South Yorkshire, England
    Posts
    2,318
    Thanks
    6
    Thanked 304 Times in 303 Posts
    In that case, you'll need to reload the form with the message next to each input, (you're using the input name? as the key, so that will be no problem to tally the respective message to each input), and you can also use JS to validate the form, (if available), in realtime, hence avoiding a reload for JS enabled clients.

  • #15
    Regular Coder
    Join Date
    Oct 2010
    Location
    Florence, MS
    Posts
    484
    Thanks
    10
    Thanked 33 Times in 32 Posts
    MattF, that is what my class is doing... The issue is what the OP states. That is why I am trying to fix.
    Notice: If you post a problem and it gets fixed, please remember to go back and place it as solved. ;)
    I always recommend the HEAD First series of books for learning a new coding language. ^_^


  •  
    Page 1 of 2 12 LastLast

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •