I’m been a PHP developer for quite some time now but until today I’ve not found a simple way to process (aka normalize, sanitize, validate, populate and display forms and it’s respective field errors).
I know that most of the PHP frameworks nowadays make this job easier but somehow I don’t feel like porting all my code to one of these frameworks, and I can’t quite understand how the form validation is implemented in Django for instance (I know, it’s Python but I really like their approach), so I though the best way would for me to post here the way I process a simple form and maybe you guys can point me in the best direction.
<?php // sample controller class _sample extends framework { // sample action function contact() { if ($this->Is->Post() === true) { $errors = array(); if ($this->Is->Set($_POST['name']) === false) { $errors['name'] = 'Please fill in your name.'; } if (($this->Is->Email($_POST['email']) === false) || ($this->Is->Set($_POST['email']) === false)) { $errors['email'] = 'Please fill in your email address.'; } if (($this->Is->Phone($_POST['contact']) === false) && ($this->Is->Mobile($_POST['contact']) === false)) { $errors['contact'] = 'Please fill in your phone (or cell phone) number.'; } if ($this->Is->Set($_POST['message']) === false) { $errors['message'] = 'Please type a message'; } // no errors, it's valid! if (empty($errors) === true) { // do stuff and redirect to 'success' / 'thank you' page } // load the form view, and let it display the errors // automatically prefill fields with $_POST values else { $this->View('contact_form', $errors); } } // load the form view for the first time else { $this->View('contact_form'); } } } ?>
As you can see, this is supposed to be a simple contact form however it takes the life out of me to validate it, I have been looking into some design patterns (Observer, Factory) but I do not feel confident if and in what way I should implement them.
You could make an abstract base class for all your forms, classes for fieldtypes, and a static class just for validating the values of various types (validateString, validateHtml, validateEmail, validateNumber, date, etc, just the methods..). Defining your form, you would define what field objects would it use, so the Form->validate() method would invoke the Field->validate() and return the filtered value or error message. Specify default error messages for the fields, but give an option to override it when defining fields in your form class.
Oh, and leave that $_POST thing. Read the post once, pass it once to the form validation and then work on filtered field values.
Another thing is there are various ways to achieve form validation depending on your needs and the architecture of your applications, it can be hard to make an all-purpose form validator when you have various approaches to your application design. Choose a way of doing your work and stick to it (regardless if it’s a ready to go framework or your own code), or whatever super-duper-form-validation you write, it will make no sense in latter projects.
One more: like Django? Good! So start programming Python in Django, you’ll really change the way of thinking how to get your job done.