Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.php > #7718 > unrolled thread

Simpler way to validate form fields?

Started byGilles <nospam@nospam.com>
First post2012-12-04 23:37 +0100
Last post2012-12-07 11:56 +0100
Articles 18 — 4 participants

Back to article view | Back to comp.lang.php


Contents

  Simpler way to validate form fields? Gilles <nospam@nospam.com> - 2012-12-04 23:37 +0100
    Re: Simpler way to validate form fields? "Beauregard T. Shagnasty" <a.nony.mous@example.invalid> - 2012-12-04 23:44 +0000
      Re: Simpler way to validate form fields? Jerry Stuckle <jstucklex@attglobal.net> - 2012-12-04 19:04 -0500
    Re: Simpler way to validate form fields? Jerry Stuckle <jstucklex@attglobal.net> - 2012-12-04 19:07 -0500
      Re: Simpler way to validate form fields? Gilles <nospam@nospam.com> - 2012-12-05 11:32 +0100
      Re: Simpler way to validate form fields? "M. Strobel" <sorry_no_mail_here@nowhere.dee> - 2012-12-05 12:49 +0100
    Re: Simpler way to validate form fields? "M. Strobel" <sorry_no_mail_here@nowhere.dee> - 2012-12-05 10:56 +0100
      Re: Simpler way to validate form fields? Gilles <nospam@nospam.com> - 2012-12-05 11:36 +0100
        Re: Simpler way to validate form fields? "M. Strobel" <sorry_no_mail_here@nowhere.dee> - 2012-12-05 11:52 +0100
        Re: Simpler way to validate form fields? "M. Strobel" <sorry_no_mail_here@nowhere.dee> - 2012-12-05 12:09 +0100
          Re: Simpler way to validate form fields? Gilles <nospam@nospam.com> - 2012-12-06 14:43 +0100
            Re: Simpler way to validate form fields? Gilles <nospam@nospam.com> - 2012-12-06 14:55 +0100
              Re: Simpler way to validate form fields? "M. Strobel" <sorry_no_mail_here@nowhere.dee> - 2012-12-06 17:50 +0100
                Re: Simpler way to validate form fields? Gilles <nospam@nospam.com> - 2012-12-06 17:51 +0100
              Re: Simpler way to validate form fields? Gilles <nospam@nospam.com> - 2012-12-06 17:50 +0100
                Re: Simpler way to validate form fields? "M. Strobel" <sorry_no_mail_here@nowhere.dee> - 2012-12-06 17:55 +0100
                  Re: Simpler way to validate form fields? Gilles <nospam@nospam.com> - 2012-12-07 11:15 +0100
                    Re: Simpler way to validate form fields? "M. Strobel" <sorry_no_mail_here@nowhere.dee> - 2012-12-07 11:56 +0100

#7718 — Simpler way to validate form fields?

FromGilles <nospam@nospam.com>
Date2012-12-04 23:37 +0100
SubjectSimpler way to validate form fields?
Message-ID<2lusb8ldn2g35j7p025r8ep45i5g1gkat2@4ax.com>
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.

[toc] | [next] | [standalone]


#7719

From"Beauregard T. Shagnasty" <a.nony.mous@example.invalid>
Date2012-12-04 23:44 +0000
Message-ID<k9m1tj$m6j$1@dont-email.me>
In reply to#7718
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/>

-- 
   -bts
   -This space for rent, but the price is high

[toc] | [prev] | [next] | [standalone]


#7720

FromJerry Stuckle <jstucklex@attglobal.net>
Date2012-12-04 19:04 -0500
Message-ID<k9m32c$1jo$1@dont-email.me>
In reply to#7719
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@attglobal.net
==================

[toc] | [prev] | [next] | [standalone]


#7721

FromJerry Stuckle <jstucklex@attglobal.net>
Date2012-12-04 19:07 -0500
Message-ID<k9m37q$2gl$1@dont-email.me>
In reply to#7718
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@attglobal.net
==================

[toc] | [prev] | [next] | [standalone]


#7726

FromGilles <nospam@nospam.com>
Date2012-12-05 11:32 +0100
Message-ID<ll8ub89k95l7j7f44sk91njnu12aeb7bdl@4ax.com>
In reply to#7721
On Tue, 04 Dec 2012 19:07:17 -0500, Jerry Stuckle
<jstucklex@attglobal.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.

[toc] | [prev] | [next] | [standalone]


#7730

From"M. Strobel" <sorry_no_mail_here@nowhere.dee>
Date2012-12-05 12:49 +0100
Message-ID<ai8qm2F7hr9U1@mid.uni-berlin.de>
In reply to#7721
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.

[toc] | [prev] | [next] | [standalone]


#7725

From"M. Strobel" <sorry_no_mail_here@nowhere.dee>
Date2012-12-05 10:56 +0100
Message-ID<ai8k28F62c0U1@mid.uni-berlin.de>
In reply to#7718
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.

[toc] | [prev] | [next] | [standalone]


#7727

FromGilles <nospam@nospam.com>
Date2012-12-05 11:36 +0100
Message-ID<2m8ub8dm7cq38dbtorvlpbs4nq85h1q3gu@4ax.com>
In reply to#7725
On Wed, 05 Dec 2012 10:56:24 +0100, "M. Strobel"
<sorry_no_mail_here@nowhere.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
}
============
?

[toc] | [prev] | [next] | [standalone]


#7728

From"M. Strobel" <sorry_no_mail_here@nowhere.dee>
Date2012-12-05 11:52 +0100
Message-ID<ai8nb0F6pl8U1@mid.uni-berlin.de>
In reply to#7727
Am 05.12.2012 11:36, schrieb Gilles:
> On Wed, 05 Dec 2012 10:56:24 +0100, "M. Strobel"
> <sorry_no_mail_here@nowhere.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.

[toc] | [prev] | [next] | [standalone]


#7729

From"M. Strobel" <sorry_no_mail_here@nowhere.dee>
Date2012-12-05 12:09 +0100
Message-ID<ai8oanF70n6U1@mid.uni-berlin.de>
In reply to#7727
Am 05.12.2012 11:36, schrieb Gilles:
> On Wed, 05 Dec 2012 10:56:24 +0100, "M. Strobel"
> <sorry_no_mail_here@nowhere.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.

[toc] | [prev] | [next] | [standalone]


#7731

FromGilles <nospam@nospam.com>
Date2012-12-06 14:43 +0100
Message-ID<oagub8t658vanhdeajl0vgkvurn2ji7cve@4ax.com>
In reply to#7729
On Wed, 05 Dec 2012 12:09:11 +0100, "M. Strobel"
<sorry_no_mail_here@nowhere.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.

[toc] | [prev] | [next] | [standalone]


#7732

FromGilles <nospam@nospam.com>
Date2012-12-06 14:55 +0100
Message-ID<qr81c8d7bqr1u7gtum1ikb840ampn9ej2u@4ax.com>
In reply to#7731
On Thu, 06 Dec 2012 14:43:57 +0100, Gilles <nospam@nospam.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");

[toc] | [prev] | [next] | [standalone]


#7733

From"M. Strobel" <sorry_no_mail_here@nowhere.dee>
Date2012-12-06 17:50 +0100
Message-ID<aic0lpFu3i7U1@mid.uni-berlin.de>
In reply to#7732
Am 06.12.2012 14:55, schrieb Gilles:
> On Thu, 06 Dec 2012 14:43:57 +0100, Gilles <nospam@nospam.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.


[toc] | [prev] | [next] | [standalone]


#7735

FromGilles <nospam@nospam.com>
Date2012-12-06 17:51 +0100
Message-ID<n7j1c8pv3rt9nr8hr7hadtkjlhvlscjfl2@4ax.com>
In reply to#7733
On Thu, 06 Dec 2012 17:50:01 +0100, "M. Strobel"
<sorry_no_mail_here@nowhere.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.

[toc] | [prev] | [next] | [standalone]


#7734

FromGilles <nospam@nospam.com>
Date2012-12-06 17:50 +0100
Message-ID<m6h1c8t93qrlcpsc7lpsvqmbd8ook9ldov@4ax.com>
In reply to#7732
On Thu, 06 Dec 2012 14:55:51 +0100, Gilles <nospam@nospam.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.

[toc] | [prev] | [next] | [standalone]


#7736

From"M. Strobel" <sorry_no_mail_here@nowhere.dee>
Date2012-12-06 17:55 +0100
Message-ID<aic0vpFu5u3U1@mid.uni-berlin.de>
In reply to#7734
Am 06.12.2012 17:50, schrieb Gilles:
> On Thu, 06 Dec 2012 14:55:51 +0100, Gilles <nospam@nospam.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.

[toc] | [prev] | [next] | [standalone]


#7742

FromGilles <nospam@nospam.com>
Date2012-12-07 11:15 +0100
Message-ID<tag3c8pk0dj2vusjn1gd7ebmhp1ik4kpk1@4ax.com>
In reply to#7736
On Thu, 06 Dec 2012 17:55:21 +0100, "M. Strobel"
<sorry_no_mail_here@nowhere.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.

[toc] | [prev] | [next] | [standalone]


#7743

From"M. Strobel" <sorry_no_mail_here@nowhere.dee>
Date2012-12-07 11:56 +0100
Message-ID<aie0bqFd55fU1@mid.uni-berlin.de>
In reply to#7742
Am 07.12.2012 11:15, schrieb Gilles:
> On Thu, 06 Dec 2012 17:55:21 +0100, "M. Strobel"
> <sorry_no_mail_here@nowhere.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.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.php


csiph-web