• 0

[PHP] Check for required fields.


Question

Hi guys.

PHP newb here. What is the best way to go about checking that all the required fields of a form are filled out and give an error if they aren't? I've been working on the following simple form and the way I have it, it gives the "Not all fields are filled out" error the moment the page is loaded instead of only on form submission.

<?php

if(!empty($_POST['name']) && !empty($_POST['review']))
{

$name = stripslashes($_POST['name']);
$br = nl2br($_POST['review']);
$review = stripslashes($br);

$msg = "<div class='review'><strong>" . $name . "</strong> said:<br />\n" . $review . "</div>\n\n";

$fp = fopen ("reviews.php", "a");
if ($fp) {
fwrite ($fp, $msg);
fclose ($fp);

$status = "<span class='success'>Success</span>";
}

}
else
{
$status = "<span class='error'>You haven't filled in all the fields you twit.</span>";
}


include("reviews.php");
echo $status;

?>

I know it must be something super simple that I am missing, my brain just isn't firing on all cylinders tonight.

Also, any further advice on how to improve the rest of the script is much appreciated.

Cheers,

Jordan

Link to comment
Share on other sites

11 answers to this question

Recommended Posts

  • 0

One way would be to have a boolean at the topped called $valid and an array called $errors = array();. Then you'd had a block for each field of the form, checking to make sure it's valid and sanitised. If anything fails, you change the boolean to false, and then add an entry into $errors detailing what went wrong.

$valid = true;
if(empty($name))
{
    $valid = false;
    $errors[] = "Name wasn't filled in";
}

if($valid)
{
    // save data
}
else
{
    foreach($errors as $error)
    {
        print $error;
    }
}

Another important point with your code is that because you're writing to a .php file, people could add PHP code in their review that would get executed when you open the page. Very nasty. A couple of handy security and auxiliary function are:

strip_tags()
htmlspecialchars()
trim()

I know there's more but I haven't really needed to use non-framework PHP in a while.

Link to comment
Share on other sites

  • 0

You could have an array of field names and check if the field names exist in $_POST array. Next you can check if these are null or not after applying a trim.

I generally perform a sequence of steps...

- Have an array of required field names.

- Loop through $_POST and check if the required field names are present and if present apply trim and collect them

- Sanitize through filters

- Regex check to make sure the input is clean.

Link to comment
Share on other sites

  • 0

Thanks for your responses guys. However, maybe I'm misunderstanding something but I still don't get how to make the "not all required fields have been filled" error NOT appear BEFORE the form has been submitted the first time. You know, when the person just arrives at the page.

Basically, how do I tell the difference between a field that was left blank when the submit button was clicked, and a field that is blank because the person just arrived at the page?

EDIT: Nevermind. I got it now. What I did not understand was that $_POST gets set (isset) when the form is submitted, even if the field is blank, but it is not set before submitting :blush: . Here is my updated code now.

<?php

if(isset($_POST['name']) && isset($_POST['review']))
{

if (empty($_POST['name']) || empty($_POST['review'])) 
{
$status = "<span class='error'>You must fill out all of the fields.</span>";
}
else
{
$name = stripslashes($_POST['name']);
$br = nl2br($_POST['review']);
$review = stripslashes($br);

$msg = "<div class='review'><strong>" . $name . "</strong> said:<br />\n" . $review . "</div>\n\n";

$fp = fopen ("reviews.php", "a");
if ($fp) {
fwrite ($fp, $msg);
fclose ($fp);
}

$status = "<span class='success'>Success</span>";
}

}

include("reviews.php");
echo $status;
?>

Link to comment
Share on other sites

  • 0

You need to run htmlentities() on those fields to make sure you can't be hurt by XSS attacks. :) Unless you want to have HTML appearing, in which case you need to remove some of the nastier tags somehow.

Link to comment
Share on other sites

  • 0

Another important point with your code is that because you're writing to a .php file, people could add PHP code in their review that would get executed when you open the page. Very nasty. A couple of handy security and auxiliary function are:

strip_tags()
htmlspecialchars()
trim()

I know there's more but I haven't really needed to use non-framework PHP in a while.

You need to run htmlentities() on those fields to make sure you can't be hurt by XSS attacks. :) Unless you want to have HTML appearing, in which case you need to remove some of the nastier tags somehow.

Ok to protect myself from people adding php into the form, I have done this:

$trimmed = trim($_POST['review']);
$stripped = strip_tags($trimmed);
$entities = htmlentities($stripped, ENT_QUOTES);
$br = nl2br($entities);
$review = stripslashes($br);

However, this doesn't seem very elegant. Is there a better way to do this?

Link to comment
Share on other sites

  • 0

You can put that in a function to clean it up a bit. For example.


function clean($string) {

$trimmed = trim($string);
$stripped = strip_tags($trimmed);
$entities = htmlentities($stripped, ENT_QUOTES);
$br = nl2br($entities);
$review = stripslashes($br);

return $review;

}

Then whenever you need it, just call the function clean.

clean($_POST['review']);

Link to comment
Share on other sites

  • 0

Ok to protect myself from people adding php into the form, I have done this:

$trimmed = trim($_POST['review']);
$stripped = strip_tags($trimmed);
$entities = htmlentities($stripped, ENT_QUOTES);
$br = nl2br($entities);
$review = stripslashes($br);

However, this doesn't seem very elegant. Is there a better way to do this?

I personally am not convinced you need to pass your POST information through that many functions, but that is another topic. Here is an "elegant" way to apply everything you want to your entire $_POST superglobal.

array_walk($_POST, create_function('&$value, $key', '$value = stripslashes(nl2br(htmlentities(strip_tags(trim($value)), ENT_QUOTES)));'));

Run this code and $_POST['review'] will be clean, as will anything else in $_POST.

Link to comment
Share on other sites

  • 0

Thanks Hot. That looks a lot neater. But what functions would you recommend then to get a clean $_POST? Like I said in my first post, I am a php newb.

Link to comment
Share on other sites

  • 0

Thanks Hot. That looks a lot neater. But what functions would you recommend then to get a clean $_POST? Like I said in my first post, I am a php newb.

Well... You probably don't need stripslashes(). Values will not be escaped on a regular form submission. This function is useful when pulling escaped information out of a database, or if your POST information came from an Ajax call that escaped the parameters (such as jQuery's), or something.

You could also safely eliminate trim() and strip_tags(), though that one is really a matter of preference. It is good practice to prune bad input. I just don't like doing it without keeping a copy of the original (so that I can see what kind of mistakes my users are making).

You should run trim() after strip_tags(), though. The way it is right now, whitespace between HTML tags (such as <strong> </strong>) would not be eliminated.

Link to comment
Share on other sites

  • 0

Well... You probably don't need stripslashes(). Values will not be escaped on a regular form submission.

Depends. PHP configuration can make them appear escaped (mainly magic_quotes_gpc).

If the script is used on multiple servers and platforms, like for example if it is used in CMS's library, it's better to check the configuration and do according to that. If the script is only used on one server, then it can be worked out by editing PHP's configuration as long as the user has rights to do it.

You could also safely eliminate trim() and strip_tags(), though that one is really a matter of preference. It is good practice to prune bad input. I just don't like doing it without keeping a copy of the original (so that I can see what kind of mistakes my users are making).

It's good to remember that strip_tags() won't validate the input. That means it can eat the whole message.

Personally I wouldn't write anything directly to inside PHP file. Even just a plain string inside plain text file placed outside public root is better.

Link to comment
Share on other sites

  • 0

ive always used if(!isset(blahblahblah)) {} to check if something has been set, at least for something like a submit button. you could use if($_POST['blah']==NULL) {} for other things like input fields. ive used that in the past without problem.

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.