#1
  1. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,653
    Rep Power
    171

    Validating arguments while instantiating=> before calling the method.


    Hello;
    1 - Which one is a better practice? Why?
    2 - In soltion I, is this the proper way of making sure I validate arguments before I allow execution of public function getHTML()? If not please help me with your modifications.

    Thank you.

    Solution I
    PHP Code:
    class textinput{
        private 
    $valid false;
        private 
    $html;
        public function 
    __construct($attributes=array())
            {
                    if(
    count($attributes)<1)
                        {
                                                  
    $this->valid=false;
                        }
                    else 
                        {    
                            
    $this->valid=true;
                            
    $this->html='<input type="text" ';
                            foreach(
    $attributes as $attribute=>$value)
                                {
                                    
    $this->html.=$attribute.'="'.$value.'" ';
                                }
                            
    $this->html.='/>';
                        }
            }
                public function 
    getHTML()
                    {
                        if(
    $this->valid==true)
                            {    
                                return 
    $this->html;
                            }
                }
    }
    $textInput=new textinput();
    echo 
    $textInput->getHTML(); 
    Solution II

    PHP Code:
    class form
            
    {
                private static 
    $valid=false;
                private static 
    $form;
                public static function 
    input_text($attributes = array())
                    {
                        if(
    count($attributes)<1)
                            {
                                
    self::$valid=false;
                            }
                        else
                            {
                                
    self::$valid=true;
                                
    self::$form '<input type = "text" ';
                                foreach(
    $attributes as $element=>$val)
                                    {
                                        
    self::$form .=' '.$element.' =  "'.$val.'" ';
                                    }
                                 
    self::$form .='>';
                                 return 
    self::$form
                            }
                    }
            }
    echo 
    form::input_text(array('name'=>'password''class'=>'text_password')); 
    Last edited by zxcvbnm; October 16th, 2012 at 01:46 AM.
  2. #2
  3. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,866
    Rep Power
    6351
    The second one is incorrect since it works on class properties without being instantiated.

    Neither of these actually checks for validity, and doesn't run the inputs through htmlentities.
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  4. #3
  5. No Profile Picture
    Lost in code
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 2004
    Posts
    8,317
    Rep Power
    7170
    Error checking in a constructor is actually one of those few cases where there are some pretty straight forward and generally well-agreed-upon rules: If the parameters passed to the constructor are invalid, you throw an exception.

    PHP Code:
    class textinput{
        private 
    $html;
        public function 
    __construct($attributes=array())
            {
                    if(
    count($attributes)<1)
                        {
                                                  throw new 
    exception("textinput must have at least one attribute");
                        }
                    else 
                        {    
                            
    $this->html='<input type="text" ';
                            foreach(
    $attributes as $attribute=>$value)
                                {
                                    
    $this->html.=$attribute.'="'.$value.'" ';
                                }
                            
    $this->html.='/>';
                        }
            }
                public function 
    getHTML()
                    {
                            return 
    $this->html;
                }
    }
    $textInput=new textinput();
    echo 
    $textInput->getHTML(); 
    One of the rules of object oriented programming is that your instantiated objects are always in a consistent and stable state. If it is logically impossible for a textinput object to exist with 0 attributes, then you should not allow a textinput object to be created with 0 attributes. The only way to prevent an object from being created is to throw an exception from the constructor (thus the simple rule).
    PHP FAQ

    Originally Posted by Spad
    Ah USB, the only rectangular connector where you have to make 3 attempts before you get it the right way around
  6. #4
  7. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,653
    Rep Power
    171
    Originally Posted by ManiacDan
    The second one is incorrect since it works on class properties without being instantiated.
    Hello. Which property are you referring to? There are only $valid and $form. Is there something I am not seeing?
    Originally Posted by ManiacDan
    Neither of these actually checks for validity, and doesn't run the inputs through htmlentities.
    I understand . What I meant was the approach to validation, not the process of validation. I assume it is ok the way I've done it. If not please poke me.

    I am really curious to know which one - and why - is a better practice. I personally think the static one is easier because it doesn't have the instantiation process. I wonder why the example doesn't offer static!
  8. #5
  9. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    May 2008
    Posts
    577
    Rep Power
    181
    I personally would stay away from a static form input class. In your simple example it can work, but if you want to really expand your functionality in the future, you'll have a much easier time instantiating one form at a time. But if you are just testing code and asking for an academia response, than I'm probably not the guy for the job.
  10. #6
  11. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,653
    Rep Power
    171
    Originally Posted by E-Oreo
    The only way to prevent an object from being created is to throw an exception from the constructor (thus the simple rule).
    Ahah. This is the phrase I have been craving. I am gonna run some testing and get back.
    -----------
    EDIT:

    Ok "throw new exception" stops it from instantiating (the point of this thread)! Now how can I make it to show a nice message instead of the fatal error?
    PHP Code:
    if(1==1)
        {
            throw new 
    exception("textinput must have at least one attribute");
        } 
    This shows a nasty fatal error:s
    <br />
    <b>Fatal error</b>: Uncaught exception 'Exception' with message 'textinput must have at least one attribute' in C:\Program Files\Zend\Apache2\htdocs\test_folder\form.php:76
    Stack trace:
    #0 C:\Users\User\AppData\Local\Temp\dummy.php(1): include()
    #1 {main}
    thrown in <b>C:\Program Files\Zend\Apache2\htdocs\test_folder\form.php</b> on line <b>76</b><br />
    Last edited by zxcvbnm; October 16th, 2012 at 10:27 PM.
  12. #7
  13. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    when you throw an exception it is good practice to catch it again (so much so that not catching en exception produces a fatal error), eg

    PHP Code:
    //In this example $testForm, $some_global_error_store and formatErrors() are completely fictional

    /*...*/

    try {
         
    $form = new testForm();
    } catch(
    Execption $e) {
         
    $some_global_error_store[] = $e->getMessage();
    }

    /*...*/

    $errormsg formatErrors($some_global_error_store);

    /*...*/

    echo $errormsg;

    /*...*/ 
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  14. #8
  15. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,653
    Rep Power
    171
    Originally Posted by Northie
    when you throw an exception it is good practice to catch it again (so much so that not catching en exception produces a fatal error), eg

    PHP Code:
    //In this example $testForm, $some_global_error_store and formatErrors() are completely fictional

    /*...*/

    try {
         
    $form = new testForm();
    } catch(
    Execption $e) {
         
    $some_global_error_store[] = $e->getMessage();
    }

    /*...*/

    $errormsg formatErrors($some_global_error_store);

    /*...*/

    echo $errormsg;

    /*...*/ 
    Looks like it's not compulsory to throw stuff then : )
    PHP Code:
    try
        {
            
    $dbh = new PDO ''.HOST_DB.''USERPASS );
        }
    catch(
    Exception $e)
        {
            
    $error true;
            
    $connection_error_msg $e->getMessage();
        }
    //Further down the code in the appropriate place:
    if($error==true)
        {
            echo 
    $connection_error_msg;
        } 
  16. #9
  17. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    In that example, PDO may throw its own exception, of type PDOException which would be caught by your catch block

    You may extend the exception class so you may differentiate between exceptions and you can have many catches for one try, eg

    PHP Code:
    //

    try { 
        
    $form = new testForm(); 
        if(!
    $form) {
            throw new 
    Exception ("My form failed");
        }
    } catch(
    PDOExecption $e) { 
        
    //this catches the PDO exception
        
    $some_global_error_store[] = $e->getMessage(); 
        
    //code here could be different from below
    }  catch(Execption $e) { 
        
    //this catches your exception
        
    $some_global_error_store[] = $e->getMessage(); 
        
    //code here could be different from above

    There's no point "try"ing something if the code will never "throw" anything (ie you never code a throw statement)
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  18. #10
  19. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,653
    Rep Power
    171
    Originally Posted by Northie
    There's no point "try"ing something if the code will never "throw" anything (ie you never code a throw statement)
    Umm, so I am not getting it. I can't see your code throwing anything:
    PHP Code:
    try
        {
            
    $dbh = new PDO ''.HOST_DB.''USERPASS );
        }
    catch(
    Exception $e)
        {
            
    $error true;
            
    $connection_error_msg $e->getMessage();
        }
    //Further down the code in the appropriate place:
    if($error==true)
        {
            echo 
    $connection_error_msg;
        } 
  20. #11
  21. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    Originally Posted by zxcvbnm
    Umm, so I am not getting it. I can't see your code throwing anything
    lets look at the first line of my prevois reply:

    Originally Posted by Northie
    In that example, PDO may throw its own exception
    maybe you don;t understand this sentance.

    When you write

    PHP Code:
    new PDO(/**/); 
    you are creating a PDO object, during the creation of that object PHP its self may throw an exception of type PDOException....pretend it was a class you write and have peppered it with throw statements where you felt was necessary

    You are therefore implicitly writing code that could throw exceptions
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  22. #12
  23. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,866
    Rep Power
    6351
    Maybe this is the misunderstanding: Thrown exceptions "bubble up" through everything. Function calls, object creation, everything. They stop bubbling when they hit a try/catch block, or when they hit "the surface" of the application, and fatal error. Creating a new PDO object invokes thousands of lines of code, any one of which can be a throw.
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.

IMN logo majestic logo threadwatch logo seochat tools logo