Simpler way to validate form fields? [message #179786] |
Tue, 04 December 2012 22:37 |
Gilles Ganault
Messages: 27 Registered: September 2010
Karma: 0
|
Junior Member |
|
|
Hello
If this the best way to validate each and every field in a form, or is
there a better/simpler way?
http://phpmaster.com/form-validation-with-php/
(section "Validating the Form Contents")
Sample:
========
$nameErr = $addrErr = "";
$name = $address "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["name"])) {
$nameErr = "Missing";
}
else {
$name = $_POST["name"];
}
etc.
========
Thank you.
|
|
|
|
Re: Simpler way to validate form fields? [message #179788 is a reply to message #179787] |
Wed, 05 December 2012 00:04 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 12/4/2012 6:44 PM, Beauregard T. Shagnasty wrote:
> Gilles wrote:
>
>> If this the best way to validate each and every field in a form, or is
>> there a better/simpler way?
>>
>> http://phpmaster.com/form-validation-with-php/
>> (section "Validating the Form Contents")
>>
>> Sample:
>> ========
>
> I've always liked this fellow's compactness.
>
> <http://safalra.com/programming/php/contact-feedback-form/>
>
A lot of problems in that code. For instance, you shouldn't use
stripslashes() unless magic_quotes_gpc is enabled (which is shouldn't
be). Additionally, the code doesn't check to see if the elements of the
$_POST array are actually set before testing them. It also uses the
deprecated function eregi(), and the test fails several valid email
addresses while rejecting many valid ones.
Not a very good example at all, IMHO.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Simpler way to validate form fields? [message #179789 is a reply to message #179786] |
Wed, 05 December 2012 00:07 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 12/4/2012 5:37 PM, Gilles wrote:
> Hello
>
> If this the best way to validate each and every field in a form, or is
> there a better/simpler way?
>
> http://phpmaster.com/form-validation-with-php/
> (section "Validating the Form Contents")
>
> Sample:
> ========
> $nameErr = $addrErr = "";
> $name = $address "";
>
> if ($_SERVER["REQUEST_METHOD"] == "POST") {
> if (empty($_POST["name"])) {
> $nameErr = "Missing";
> }
> else {
> $name = $_POST["name"];
> }
> etc.
> ========
>
> Thank you.
>
Hi,
In most cases I prefer isset() over empty - an array element may be set
but may not contain data. Those can be two different errors.
Otherwise, I do pretty much the same thing. Be sure to validate the
contents also, not just the presence of the value.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Simpler way to validate form fields? [message #179793 is a reply to message #179786] |
Wed, 05 December 2012 09:56 |
M. Strobel
Messages: 386 Registered: December 2011
Karma: 0
|
Senior Member |
|
|
Am 04.12.2012 23:37, schrieb Gilles:
> Hello
>
> If this the best way to validate each and every field in a form, or is
> there a better/simpler way?
>
> http://phpmaster.com/form-validation-with-php/
> (section "Validating the Form Contents")
>
> Sample:
> ========
> $nameErr = $addrErr = "";
> $name = $address "";
>
> if ($_SERVER["REQUEST_METHOD"] == "POST") {
> if (empty($_POST["name"])) {
> $nameErr = "Missing";
> }
> else {
> $name = $_POST["name"];
> }
> etc.
> ========
Too basic. My user input reader is
function getStringFromForm($key, $l=255, $val=null) {
return (isset($_REQUEST[$key])) ?
filter_var(substr($_REQUEST[$key],0,$l), FILTER_SANITIZE_STRING) :
$val;
}
Short explanation:
I have a default length limit, which might stop overflow/overload attacks.
The default value is settable, no coding like: if empty() set to "something".
I read $_REQUEST, because the first thing my dispatcher does is a check for GET/POST,
and POST form values can be as easily manipulated as get values. So EVERY string
input uses this function.
Of course there is a corresponding getEmailFromForm() and getIntFromForm().
/Str.
|
|
|
Re: Simpler way to validate form fields? [message #179794 is a reply to message #179789] |
Wed, 05 December 2012 10:32 |
Gilles Ganault
Messages: 27 Registered: September 2010
Karma: 0
|
Junior Member |
|
|
On Tue, 04 Dec 2012 19:07:17 -0500, Jerry Stuckle
<jstucklex(at)attglobal(dot)net> wrote:
> In most cases I prefer isset() over empty - an array element may be set
> but may not contain data. Those can be two different errors.
>
> Otherwise, I do pretty much the same thing. Be sure to validate the
> contents also, not just the presence of the value.
Good to know. Thanks for the input.
|
|
|
Re: Simpler way to validate form fields? [message #179795 is a reply to message #179793] |
Wed, 05 December 2012 10:36 |
Gilles Ganault
Messages: 27 Registered: September 2010
Karma: 0
|
Junior Member |
|
|
On Wed, 05 Dec 2012 10:56:24 +0100, "M. Strobel"
<sorry_no_mail_here(at)nowhere(dot)dee> wrote:
> Too basic. My user input reader is
>
> function getStringFromForm($key, $l=255, $val=null) {
> return (isset($_REQUEST[$key])) ?
> filter_var(substr($_REQUEST[$key],0,$l), FILTER_SANITIZE_STRING) :
> $val;
> }
>
[...]
> I read $_REQUEST, because the first thing my dispatcher does is a check for GET/POST,
> and POST form values can be as easily manipulated as get values. So EVERY string
> input uses this function.
Thanks much for the code. I'm not sure I understand what you mean
about checking for GET/POST. Do you mean this?
============
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
//Call getStringFromForm, getEmailFromForm, and getIntFromForm
//for each form field
}
============
?
|
|
|
Re: Simpler way to validate form fields? [message #179796 is a reply to message #179795] |
Wed, 05 December 2012 10:52 |
M. Strobel
Messages: 386 Registered: December 2011
Karma: 0
|
Senior Member |
|
|
Am 05.12.2012 11:36, schrieb Gilles:
> On Wed, 05 Dec 2012 10:56:24 +0100, "M. Strobel"
> <sorry_no_mail_here(at)nowhere(dot)dee> wrote:
>> Too basic. My user input reader is
>>
>> function getStringFromForm($key, $l=255, $val=null) {
>> return (isset($_REQUEST[$key])) ?
>> filter_var(substr($_REQUEST[$key],0,$l), FILTER_SANITIZE_STRING) :
>> $val;
>> }
>>
> [...]
>> I read $_REQUEST, because the first thing my dispatcher does is a check for GET/POST,
>> and POST form values can be as easily manipulated as get values. So EVERY string
>> input uses this function.
>
> Thanks much for the code. I'm not sure I understand what you mean
> about checking for GET/POST. Do you mean this?
>
> ============
> if ($_SERVER['REQUEST_METHOD'] === 'POST') {
> //Call getStringFromForm, getEmailFromForm, and getIntFromForm
> //for each form field
> }
> ============
> ?
Yes. The idea is to read only expected data.
Then the idea is to have your input filter adjusted in one place if it fails somehow.
This must be coupled with prepared statements for the database insert (against SQL
injection), and a output filter that converts special chars to entities (against XSS).
That's about it.
/Str.
|
|
|
Re: Simpler way to validate form fields? [message #179797 is a reply to message #179795] |
Wed, 05 December 2012 11:09 |
M. Strobel
Messages: 386 Registered: December 2011
Karma: 0
|
Senior Member |
|
|
Am 05.12.2012 11:36, schrieb Gilles:
> On Wed, 05 Dec 2012 10:56:24 +0100, "M. Strobel"
> <sorry_no_mail_here(at)nowhere(dot)dee> wrote:
>> Too basic. My user input reader is
>>
>> function getStringFromForm($key, $l=255, $val=null) {
>> return (isset($_REQUEST[$key])) ?
>> filter_var(substr($_REQUEST[$key],0,$l), FILTER_SANITIZE_STRING) :
>> $val;
>> }
>>
> [...]
>> I read $_REQUEST, because the first thing my dispatcher does is a check for GET/POST,
>> and POST form values can be as easily manipulated as get values. So EVERY string
>> input uses this function.
>
> Thanks much for the code. I'm not sure I understand what you mean
> about checking for GET/POST. Do you mean this?
>
> ============
> if ($_SERVER['REQUEST_METHOD'] === 'POST') {
> //Call getStringFromForm, getEmailFromForm, and getIntFromForm
> //for each form field
> }
> ============
One more observation to the default value val:
with getIntFromForm() the settable default is especially useful, because PHP likes to
return integer 0 for an empty input. Example:
php > echo 'simple conversion to integer: ', (int) '', PHP_EOL;
simple conversion to integer: 0
php >
With my function design you decide at call time which default value you want to have,
without cluttering your code with if branches.
/Str.
|
|
|
Re: Simpler way to validate form fields? [message #179798 is a reply to message #179789] |
Wed, 05 December 2012 11:49 |
M. Strobel
Messages: 386 Registered: December 2011
Karma: 0
|
Senior Member |
|
|
Am 05.12.2012 01:07, schrieb Jerry Stuckle:
> In most cases I prefer isset() over empty - an array element may be set but may not
> contain data. Those can be two different errors.
Same here. I think you should always use isset() in the first place, because clean
code does not access unset variables.
And if empty() is allowed depends on the case at hand.
/Str.
|
|
|
Re: Simpler way to validate form fields? [message #179799 is a reply to message #179797] |
Thu, 06 December 2012 13:43 |
Gilles Ganault
Messages: 27 Registered: September 2010
Karma: 0
|
Junior Member |
|
|
On Wed, 05 Dec 2012 12:09:11 +0100, "M. Strobel"
<sorry_no_mail_here(at)nowhere(dot)dee> wrote:
> One more observation to the default value val:
>
> with getIntFromForm() the settable default is especially useful, because PHP likes to
> return integer 0 for an empty input.
Thanks for the input. I modified the above to check for a dd/mm/yyyy
date, but PHP returns nothing so I guess I'm using filter_var()
wrongly with its regex option:
==============
#!"C:\Projects\Php\dummyl\php-cgi.exe"
<?php
function getDateFromForm($key, $l=8, $val=null) {
//Check for date DD/MM/YYYY
return (isset($_POST[$key])) ?
filter_var(substr($_POST[$key],0,$l),
FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>"/^\d{2}\/\d{2}\/\d{4}/ "))
)
: $val;
}
//http://192.168.0.1/test.php?mydate=01/02/2012
print getDateFromForm("mydate");
==============
Thank you.
|
|
|
Re: Simpler way to validate form fields? [message #179800 is a reply to message #179799] |
Thu, 06 December 2012 13:55 |
Gilles Ganault
Messages: 27 Registered: September 2010
Karma: 0
|
Junior Member |
|
|
On Thu, 06 Dec 2012 14:43:57 +0100, Gilles <nospam(at)nospam(dot)com> wrote:
> function getDateFromForm($key, $l=8, $val=null) {
> //Check for date DD/MM/YYYY
> return (isset($_POST[$key])) ?
> filter_var(substr($_POST[$key],0,$l),
>
> FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>"/^\d{2}\/\d{2}\/\d{4}/ "))
> )
> : $val;
> }
I made a mistake, but even after turning $_POST into $_GET, it still
displays nothing:
function getDateFromForm($key, $l=8, $val=null) {
//Check for date DD/MM/YYYY
return (isset($_GET[$key])) ?
filter_var(substr($_GET[$key],0,$l),
FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>"/^\d{2}\/\d{2}\/\d{4}/ "))
)
: $val;
}
//http://192.168.0.1/test.php?mydate=01/02/2012
print getDateFromForm("mydate");
|
|
|
Re: Simpler way to validate form fields? [message #179801 is a reply to message #179800] |
Thu, 06 December 2012 16:50 |
Gilles Ganault
Messages: 27 Registered: September 2010
Karma: 0
|
Junior Member |
|
|
On Thu, 06 Dec 2012 14:55:51 +0100, Gilles <nospam(at)nospam(dot)com> wrote:
> function getDateFromForm($key, $l=8, $val=null) {
> //Check for date DD/MM/YYYY
> return (isset($_GET[$key])) ?
> filter_var(substr($_GET[$key],0,$l),
>
> FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>"/^\d{2}\/\d{2}\/\d{4}/ "))
> )
> : $val;
> }
>
> //http://192.168.0.1/test.php?mydate=01/02/2012
> print getDateFromForm("mydate");
Turns out I should have used "/^\d{2}\/\d{2}\/\d{4}$/". Regardless,
this doesn't check that the date looks kosher, eg. 99/99/9999 is
considered OK, so it looks like it's loetter to use something else
such as:
if (DateTime::createFromFormat('d/m/Y', $string))
Thanks for the help.
|
|
|
Re: Simpler way to validate form fields? [message #179802 is a reply to message #179800] |
Thu, 06 December 2012 16:50 |
M. Strobel
Messages: 386 Registered: December 2011
Karma: 0
|
Senior Member |
|
|
Am 06.12.2012 14:55, schrieb Gilles:
> On Thu, 06 Dec 2012 14:43:57 +0100, Gilles <nospam(at)nospam(dot)com> wrote:
>
>> function getDateFromForm($key, $l=8, $val=null) {
>> //Check for date DD/MM/YYYY
>> return (isset($_POST[$key])) ?
>> filter_var(substr($_POST[$key],0,$l),
>>
>> FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>"/^\d{2}\/\d{2}\/\d{4}/ "))
>> )
>> : $val;
>> }
>
> I made a mistake, but even after turning $_POST into $_GET, it still
> displays nothing:
>
> function getDateFromForm($key, $l=8, $val=null) {
> //Check for date DD/MM/YYYY
> return (isset($_GET[$key])) ?
> filter_var(substr($_GET[$key],0,$l),
>
> FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>"/^\d{2}\/\d{2}\/\d{4}/ "))
> )
> : $val;
> }
>
> //http://192.168.0.1/test.php?mydate=01/02/2012
> print getDateFromForm("mydate");
I don't know offhand what exactly PHP makes of your GET URL, but be aware that the
forward slash is a path separator.
The regex is okay. Find ways to quickly test code bits, or functions, if possible
just use the command line. My test (newlines inserted for reading):
php > $d = "01/01/2112";
php > echo filter_var($d,
FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>"/^\d{2}\/\d{2}\/\d{4}/ "))),
PHP_EOL;
01/01/2112
php > echo urlencode($d), PHP_EOL;
01%2F01%2F2112
Write regexp here with a different separator, easier to read:
array("regexp"=>"#^\d{2}/\d{2}/\d{4}#")
/Str.
|
|
|
Re: Simpler way to validate form fields? [message #179803 is a reply to message #179802] |
Thu, 06 December 2012 16:51 |
Gilles Ganault
Messages: 27 Registered: September 2010
Karma: 0
|
Junior Member |
|
|
On Thu, 06 Dec 2012 17:50:01 +0100, "M. Strobel"
<sorry_no_mail_here(at)nowhere(dot)dee> wrote:
> I don't know offhand what exactly PHP makes of your GET URL, but be aware that the
> forward slash is a path separator.
>
> The regex is okay. Find ways to quickly test code bits, or functions, if possible
> just use the command line. My test (newlines inserted for reading):
>
> php > $d = "01/01/2112";
> php > echo filter_var($d,
> FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>"/^\d{2}\/\d{2}\/\d{4}/ "))),
> PHP_EOL;
>
> 01/01/2112
>
> php > echo urlencode($d), PHP_EOL;
>
> 01%2F01%2F2112
>
> Write regexp here with a different separator, easier to read:
> array("regexp"=>"#^\d{2}/\d{2}/\d{4}#")
Thanks much for the tips.
|
|
|
Re: Simpler way to validate form fields? [message #179804 is a reply to message #179801] |
Thu, 06 December 2012 16:55 |
M. Strobel
Messages: 386 Registered: December 2011
Karma: 0
|
Senior Member |
|
|
Am 06.12.2012 17:50, schrieb Gilles:
> On Thu, 06 Dec 2012 14:55:51 +0100, Gilles <nospam(at)nospam(dot)com> wrote:
>> function getDateFromForm($key, $l=8, $val=null) {
>> //Check for date DD/MM/YYYY
>> return (isset($_GET[$key])) ?
>> filter_var(substr($_GET[$key],0,$l),
>>
>> FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>"/^\d{2}\/\d{2}\/\d{4}/ "))
>> )
>> : $val;
>> }
>>
>> //http://192.168.0.1/test.php?mydate=01/02/2012
>> print getDateFromForm("mydate");
>
> Turns out I should have used "/^\d{2}\/\d{2}\/\d{4}$/". Regardless,
> this doesn't check that the date looks kosher, eg. 99/99/9999 is
> considered OK, so it looks like it's loetter to use something else
> such as:
>
> if (DateTime::createFromFormat('d/m/Y', $string))
The date verification problems are a all time favorite in programming.
But to the regular expression: they just pick the pattern where they find it, so this
is always a tolerant and save input reading. You might as well leave off the ^ and $
delimiters.
/Str.
|
|
|
Re: Simpler way to validate form fields? [message #179810 is a reply to message #179804] |
Fri, 07 December 2012 10:15 |
Gilles Ganault
Messages: 27 Registered: September 2010
Karma: 0
|
Junior Member |
|
|
On Thu, 06 Dec 2012 17:55:21 +0100, "M. Strobel"
<sorry_no_mail_here(at)nowhere(dot)dee> wrote:
> The date verification problems are a all time favorite in programming.
>
> But to the regular expression: they just pick the pattern where they find it, so this
> is always a tolerant and save input reading. You might as well leave off the ^ and $
> delimiters.
It's better to keep ^.../ so that it doesn't allow garbage like
"qdfqdflqk 11/11/2000 qsdjflqksdfjql".
I'll try to find a good article that explains the different tips and
tricks to validate form fields, locally through JavaScript and
remotely through PHP, including anti-SPAM solutions.
Thank you.
|
|
|
Re: Simpler way to validate form fields? [message #179811 is a reply to message #179810] |
Fri, 07 December 2012 10:56 |
M. Strobel
Messages: 386 Registered: December 2011
Karma: 0
|
Senior Member |
|
|
Am 07.12.2012 11:15, schrieb Gilles:
> On Thu, 06 Dec 2012 17:55:21 +0100, "M. Strobel"
> <sorry_no_mail_here(at)nowhere(dot)dee> wrote:
>> The date verification problems are a all time favorite in programming.
>>
>> But to the regular expression: they just pick the pattern where they find it, so this
>> is always a tolerant and save input reading. You might as well leave off the ^ and $
>> delimiters.
>
> It's better to keep ^.../ so that it doesn't allow garbage like
> "qdfqdflqk 11/11/2000 qsdjflqksdfjql".
Your decision. I think error tolerant is more user friendly. And you can be sure,
that a regular expression is the best possible input filter, no need for filter_var()
in this case.
/Str.
P.S. I am waiting for someone to point out that only the best possible regexp is the
best possible input filter.
|
|
|