You are viewing...

I hate PHP Form Validation and I think I've simplified it.

Updated on December 24, 2012 at the 13th hour
Posted under:

DISCLAIMER: All views are considered my own and you should not draw any conclusions on associates.

Form validation is the scourge of my life. Have you ever tried to validate a form on your own and end up with a mountain of if/elseif/else statements and maybe a success variable to check on? Yes me too, even right now. I really really want to end this, but how? I think I've come up with a simpler way of doing it and it involves using objects, but first an intro to my problem.

The Problem


Let's say you start a project today and you are like me. You hate writing what it seems to be like ENDLESS AND GRUELING IF/ELSEIF/ELSE statements, then you've seen this:
$name = $_POST['name']; // A String with min and max lengths rule and limited character set
$positions = $_POST['positions']; // This is an array of strings all just like name
$shortName = $_POST['shortName']; // A String with a max length and must be alphabet only

Now we start the validation process (all code here is written to express the idea, not to perfect, as you have your own ideas oh how things should look)
if(($name == NULL) || ($positions == NULL) || ($shortName == NULL))
$error = "You are missing a field";
elseif(strlen($name) > 60 || strlen($name) < 4)
$error = "Name had invalid length"
elseif(strlen($shortName) > 60 || strlen($shortName) < 4)
$error = "Name had invalid length"

I won't write everything, but you get my drift, but how do we check the array? That's not easy... oh right use and else statement to do a foreach with the same if elseif else crap. It is simple, but it is complicated to read later... especially with the array

The TaskNode


I attempted to solve this by writing up something called a TaskNode, which starts off with a description and a lambda function that returns a bool. This TaskNode uses a publish/subscribe model, where you subscribe either to the success queue or failure queue. When the task is completed, one of the queues is processed depending on the return code of the lambda. This is a way to segment the null checking, length checking and and other rules you want to add. It is quite simple and the process looked efficient in hindsight, but now I think I need a better way of going about this.

My Proposed Solution


I've been doing a lot of headbanging and thinking, but you know what, my solution uses something called an SDValidator. SDValidator contains static methods called IsNull, IsLengthBetween, IsLengthGreaterThan, IsLengthLessThan. What is the kicker? Let's use isNull as an example and use the variables form above as well.

$data = $_POST;
SDValidator::isNull($data); // Returns array of keys that are null


Wow, 1 line to rule it all. Let me explain. IsNull takes in an array of data and an array of required keys (if you want to limit it). Now what it does is traverse every key in the dataset or in the case of having required keys it will take the intersection of required keys with $data and traverse that for null values. Keys with null will be returned. If the data contains an array as in the case with $positions, the array key and the numbers/keys associated with $positions with be included in the same structure. This means if the $positions value itself is null then it is included alone or if it is an array with null values then [0 => ['positions', [key0, key1, key2]]] is returned.

How does this lend itself to checkLengthBetween for instance? Same method signature as IsNull, but instead the requiredKeys is a required argument and has a structure where every key must have an array that has the min and max. This format extends itself to greaterthan, lessthan, hasInvalidChars, etc...

By returning required keys, you can return these to your client and have your client highlight those fields along with an error message. Does this completely get rid of if else statements? No, but it shortens them and instead segment if else statements by category of errors, which is a HECKUVA lot shorter any day. Use in conjunction with TaskNodes and we can completely forget else statements.

Why SDValidator?


SDValidator. Doesn't that sound cool? The way it flows when you say it. SD...Validator. S.....D....VALIDATOR, Haha, I'm just joking. SD stand for Simple Data, so Simple Data Validator.

Conclusion


You want code? You'll get it as part of my Excerion Open Sores release along with my ExClass object which is another great utility for injecting static and public methods and data into a class and storing the differences when modifying an object.

Now there's always a chance someone else has done this already and that's fine. I like thinking about how to solve my own issues more than grabbing frameworks to solve them. I think you can guess why I haven't talked about using a framework then. I don't use any Frameworks because they make assumptions about your issues and are built for general purpose issues. I like building from the ground up much more than the next guy. There are times when it is perfectly acceptable to use a framework, but then you will have to make sure you stay up to date with everything. I like looking at my code and modifying it from time to time and the fact that I can break things that other things depend on and fix it with the same structure/functions/etc. means I've learned one of the most valuable techniques in Software Engineering.
You just read "I hate PHP Form Validation and I think I've simplified it.". Please share if you liked it!
You can read more recent posts here.