SitePoint Sponsor

User Tag List

Results 1 to 16 of 16
  1. #1
    SitePoint Member
    Join Date
    May 2009
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Help needed regarding Validations

    Hello,
    I normally do all the validations (e.g. valid email, digits only etc) on php script when a page is post back to the server, and if all validations are passed then execute the method of the class to save the data. There is no validations done in class itself (in setter methods for public properties). Is this the right thing?

    1. what is the best place to run the validations? I mean should it be done in the controller/script or should it be done by the business class itself?
    2. Should i do the validations in both script and in class as well?
    3. Can anyone provide me some links about best practices for the validations?

    Thanks.

  2. #2
    SitePoint Enthusiast
    Join Date
    Dec 2003
    Location
    norway
    Posts
    61
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think it shuld be done in the business class..

    Code PHP:
    $obj = new Car();
     
    $obj->SetVal('x');
     
    if($obj->Save()){
    //success
     
    }else{
    //fail
     
    $obj->GetErrors()
     
    }

    The reason is that the object could be changed from different places in the application. There are business rules validation as well as data integretity validation that need to take place..
    I am also lookling for a good implementation/best practices for this..

  3. #3
    SitePoint Member
    Join Date
    May 2009
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Right, I also think that validation must also be done in the setter methods for the properties and if any invalid value is passed, it show set some error message.
    From you example, I would be doing something like this,
    1. Have an array for Error Messages in the class.
    2. In the setter method, check for valid data, if any error then add a message in the validation error array. Here we will just set the error message in the array and will move ahead to next action.
    3. In my every method of class (like save, update etc), first check the errors array, if it is empty, then perform the actions, else return error array.


    Right?

  4. #4
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,046
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    I don't believe its the models responsibility to validate data. Data should be valid before ever changing the models state. Validation is something that is controlled. I believe the models only responsibility is to provide communication between the domain and database. This doesn't include the responsibility of validating data in my opinion.

  5. #5
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    I would say, you should have a separate object to validate your object, like so.
    PHP Code:
    $oRedCarColourValidator = new CarColourValidator(array('colour' => 'red'));
    $oCar = new Car('red');
    if(
    $oRedCarColourValidator->isValid($oCar))
    {
        
    #valid
    }
    else
    {
        echo 
    $oRedCarColourValidator->getError(); #Car is not red.

    PHP Code:
    class Car
    {
        protected 
    $sColour;
        
        public function 
    __construct($sColour)
        {
            
    $this->sColour $sColour;
        }
        
        public function 
    getColour()
        {
            return 
    $this->sColour;
        }

    PHP Code:
    class CarColourValidator extends Validator
    {
        public function 
    isValid($mSubject)
        {
            if(
    $mSubject->getColour() === $this->getOption('colour'))
            {
                return 
    true;
            }
            
    $this->setError('Car is not red.');
            return 
    false;
        }

    PHP Code:
    abstract class Validator
    {
        private 
    $aOptions;

        private 
    $sError null;

        
    /**
         *
         * @param Array $aOptions
         */
        
    public function __construct($aOptions = array())
        {
            
    $this->aOptions $aOptions;
        }
        
    /**
         *
         * @param String $sName
         * @param Mixed $mValue
         */
        
    public function setOption($sName$mValue)
        {
            
    $this->aOptions[$sName] = $mValue;
        }

        
    /**
         *
         * @param String $sName
         * @return Mixed
         */
        
    public function getOption($sName)
        {
            return 
    $this->aOptions[$sName];
        }

        
    /**
         *
         * @param String $sError
         */
        
    protected function setError($sError)
        {
            
    $this->sError $sError;
        }

        
    /**
         *
         * @return String
         */
        
    public function getError()
        {
            return 
    $this->sError;
        }

        abstract public function 
    isValid($mSubject);

    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  6. #6
    messing with my mind fristi's Avatar
    Join Date
    Feb 2009
    Posts
    292
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have done something similar to what oddz is describing. I made a class which validates and does some needed processing on Form Data. When everything is correct the class can output all the data (stored in arrays). This data will then be passed on to a query manager which will save it to a database.
    To PHP or to Perl, that is the question!
    (Bucket - simpletest) User

  7. #7
    SitePoint Member
    Join Date
    May 2009
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Let just say I am not using any MVC framework, just a PHP file with a form and server script and a business class (e.g. Users class). On my php page, I just creates an object of user class, sets it properties and calls the save method.
    Now where to validate the data? Before passing to the object or inside the setter methods?
    Please note that i also need to show the error message to the user as well.

  8. #8
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,046
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    I don't think its wrong to validate whether or not data is compatible with the model field data type. However, string matching type validation is outside the responsibility of the model. So checking whether data is compatible with a varchar(15) would be alright for a user name perhaps. However, checking that the user name doesn't contain any spaces and has at least one alphabetic character is more or less a controller level constraint.

  9. #9
    SitePoint Addict Mastodont's Avatar
    Join Date
    Mar 2007
    Location
    Czech Republic
    Posts
    375
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    naveed83:
    validation must also be done in the setter methods for the properties
    How would you in this case check dependencies between different properties, if first setter is called?

    Now where to validate the data? Before passing to the object or inside the setter methods?
    I vote for separate method, after passing to object.
    PHP Code:
    if ( $model->Validate($array) ) {
       
    $model->Save(); // Validate can store $array internally
    } else {
      
    $errors $model->GetValidationErrors();

    oddz:string matching type validation is outside the responsibility of the model
    Could you please elaborate on this? Do you want to put validation routines into controller?

  10. #10
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Trying to isolate "validation" as a separate concept, doesn't work that well, IMHO. Some would fit best in the model layer. Some would fit in the storage (database), some would fit in the controller layer, and some could be pushed all the way out to the view layer.

  11. #11
    SitePoint Enthusiast
    Join Date
    Dec 2003
    Location
    norway
    Posts
    61
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by naveed83 View Post
    Now where to validate the data? Before passing to the object or inside the setter methods?
    Please note that i also need to show the error message to the user as well.
    Validating every "Set" method would become tedious, since it could be many Set calls..

    I don't think its wrong to validate whether or not data is compatible with the model field data type. However, string matching type validation is outside the responsibility of the model. So checking whether data is compatible with a varchar(15) would be alright for a user name perhaps. However, checking that the user name doesn't contain any spaces and has at least one alphabetic character is more or less a controller level constraint.
    Not knowing much about the MVC paradigm, how would you handle
    changes to the model from different places ?
    Lets say you want to change username from a different view than a registration page or similar, would'nt that string validation be in two different controllers?

  12. #12
    SitePoint Addict
    Join Date
    Nov 2005
    Location
    Germany
    Posts
    235
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by naveed83 View Post
    1. what is the best place to run the validations? I mean should it be done in the controller/script or should it be done by the business class itself?
    2. Should i do the validations in both script and in class as well?
    3. Can anyone provide me some links about best practices for the validations?
    In my opinion this depends on the validation type.
    1. Validating input on the request level, no business logic involved - e.g. missing parameter or parameters changing the application flow - can be validated in the controller.
    2. Validation involving business logic should be handled in your model. Now depending on your layering:
    - The database should make use of data constraints to prevent invalid entries.
    - The model class itself should not allow invalid properties, this catches more than the db constraints.
    - More complicated validation requiring various model classes should be handles in a service layer above those.

  13. #13
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,046
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    Quote Originally Posted by Mastodont
    oddz:string matching type validation is outside the responsibility of the model
    Could you please elaborate on this? Do you want to put validation routines into controller?
    Whether or not a string matches particular pattern is no concern to the model. However, checking whether that the data can be inserted as the specified type is. So making sure that a string isn't over 15 characters for varchar(15) is the models responsibility. However, checking whether certain characters exist is a lower level validation that doesn't really matter on the model level. The model just cares that the data can be inserted. Where as the controller cares that is formatted in the correct matter.

    Quote Originally Posted by danman
    Not knowing much about the MVC paradigm, how would you handle
    changes to the model from different places ?
    Lets say you want to change username from a different view than a registration page or similar, would'nt that string validation be in two different controllers?
    Well the whole idea is to isolate that responsibility to one place (controller).

  14. #14
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,046
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    Quote Originally Posted by naveed83
    validation must also be done in the setter methods for the properties
    The problem with this is the unnecessary validation that will occur when filling containers with data from a result set. Given 100 rows of data being converted to objects that is 100 unnecessary processes. If the data where invalid it wouldn't be in the database.

  15. #15
    SitePoint Addict Mastodont's Avatar
    Join Date
    Mar 2007
    Location
    Czech Republic
    Posts
    375
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    oddz:
    The model just cares that the data can be inserted. Where as the controller cares that is formatted in the correct matter.
    It sounds like you take model only as database layer and business rules should reside in controller. This is IMHO incorrect.

  16. #16
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by oddz View Post
    Where as the controller cares that is formatted in the correct matter.
    Forgive my ignorance (because that's what it is ), but wouldn't this be violating the Single Responsibility Principle?

    If this was simply a matter of have 3 objects, a model, view and a controller I guess it could be arguable - but shouldn't the controller, just well, control?

    Again, I'm not really au fair with OOP, but would you not just wrap a validation object around the insertion model?

    Anthony.
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.


Bookmarks

Posting Permissions

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