Recommendations on sharing validation rules between Javascript and PHP?
Asked Answered
O

2

13

We're in the process of writing a new form which our front-end coder has included lots and lots of JavaScript validation (technically, jQuery Tools validation).

I'm writing the PHP server-side part of the process, and of course, my own code will be doing its own validation of the data received.

Rather than have to maintain two sets of validation rules -- jQuery and PHP -- do you have any recommendations about a way to create a central list of validation rules -- i.e. field X must be size > 1 and < 10, etc. -- so I could change a validation rule in a single file or database table that would then be passed both to PHP and to jQuery?

For instance, change that same rule I mentioned above "field X must be size > 1 and < 10" to "field X must be size > 3 and < 5" and all I would have to do is edit a file or database table and both PHP and jQuery would retrieve and parse that data accordingly?

Thanks in advance for your help,

Phil

Ornis answered 16/4, 2012 at 23:25 Comment(8)
What kind of site are you created why do you think you would need such an advanced validation you cant really share the rules by using a file or database since the jquery cant read data from the database you may use ajax but I really do not see the point of why would you wnt to do it Another think I may recomend is to use xml to store validation rulesKeavy
This is another area where NodeJS really shines.Eddie
Abstracting simple validation rules (emails, max length, required etc.) with a database containing the rules is quite straightforward, but advanced validation, such as changing the validation logic based on the contents of another field, the current user, or based on other objects in the system, is quite complicated. Unless you have a huge amount of validation logic, I would just manually code the logic in both PHP and jQuery.Cosetta
Good question. The problem is that jquery and php validations are going to be executed differently so you would still have to maintain two sets of code. However, validating on the client side is optional but it's mandatory on the server side. Unless your server can't handle the requests or it's just too slow, I would just drop the client side validation and handle it all on the server. Quick and easy.Marielamariele
I think you should use the same variable names for both jQuery and PHP then use another script that reads from a external text file (containing the variable values) and goes through the PHP/JS files to search and replace.Manzanilla
I've done this before by writing code in a subset of JS and PHP, and evaling it on the PHP side, and echoing it to run on the client side. JS is surprisingly resilient to the kind of things you have to do to make PHP happy. I strongly recommend against doing this, except for Internet Lulz Points, however.Estelleesten
The goal is to write two sets of code, one for PHP, the other for jQuery -- but to have one common set of validation rules, as both PHP and jQuery will need to follow those rules.Ornis
@AlienWebguy: would you mind posting as an answer below some sample code in NodeJS? For instance, to demonstrate how I can keep a single set of rules in one location -- say, field X must be > 10 characters length, but < 100 characters length?Ornis
M
4

Something along these lines would probably be good:

<?php
$validation = Array(
    "field1" => Array( // "field1" is the name of the input field
        "required" => true, // or false
        "minlength" => 5, // use 0 for no minimum
        "maxlength" => 10, // use 9999 (or other high number) for no maximum
        "regex" => "^[a-zA-Z0-9]+$" // use empty string for no regex
    ),
    "field2" => .......
    ....
);
if( $_POST) {
    foreach($validation as $k=>$v) {
        if( !isset($_POST[$k])) {
            if( $v['required']) die("Field ".$k." is required");
        }
        else {
            $l = strlen($_POST[$k]);
            if( $l < $v['minlength']) die("Field ".$k." too short");
            if( $l > $v['maxlength']) die("Field ".$k." too long");
            if( !preg_match("(".$v['regex'].")",$_POST[$k])) die("Field ".$k." incorrect format");
        }
    }
    // all ok!
}
?>
<script type="text/javascript">
    (function(rules) {
        var die = function(str) {alert(str); return false;};
        document.getElementById('myForm').onsubmit = function() {
            var elms = this.elements, i, it, r, s;
            for( i in rules) {
                r = rules[i];
                it = elms.namedItem(i);
                if( typeof it == "undefined") {
                    if( r.required) return die("Field "+i+" is required");
                }
                else {
                    s = it.length;
                    if( s < r.minlength) return die("Field "+i+" too short");
                    if( s > r.maxlength) return die("Field "+i+" too short");
                    if( !s.match(new RegExp(r.regex))) return die("Field "+i+" incorrect format");
                }
            }
            return true;
        };
    })(<?=json_encode($validation)?>);
</script>

As you can see, the general idea is to define a set of rules, then the magic happens in the json_encode($validation) - this passes the rules down into the JavaScript environment. You still have to duplicate the validation code to have it run in PHP and in JS, but at least now you can add more rules without having to change the code in two places. Hope this helps!

Moffit answered 17/4, 2012 at 0:6 Comment(1)
Thank you, I like this -- I'm going to try this :)Ornis
D
3

The Nette framework does this: http://doc.nette.org/en/forms

The whole form and the validation rules are defined in a PHP file. The framework then generates HTML code with javascript validation and after submitting it performs the server-side validation.

You can even use the Forms part of the framework separately.

Descend answered 17/4, 2012 at 0:10 Comment(3)
Hi @ondrata, Nette looks similar to Zend, which is what we're using on the back-end. But we're avoiding using a Zend Form because it's a pain to layout, and we have a very complicated layout.Ornis
@PhilAG: Nette is a bit more lightweight than Zend, so probably some fitting tool (I write probably, check wisely, rolling your own might be an option, but a fitting tool is better than rollling your own).Niels
@PhilAG This could help you with the layout: doc.nette.org/en/forms#toc-manual-rendering Basically, you write the HTML around controls and Nette generates only the <input>'s (and <form>).Descend

© 2022 - 2024 — McMap. All rights reserved.