Reputation:
If have a problem on my site that users can post empty messages if they use space.
if (isset($_POST['submit'])) {
// check for empty fields
if (empty($_POST['headline']) || empty($_POST['text']) ||
empty($_POST['forum_id'])) {
header("Refresh: 2; url=/add-thread");
die('You must fill out every field.');
}
// No errors? Save.
else {
$headline = mysql_real_escape_string($_POST['headline']);
$text = mysql_real_escape_string($_POST['text']);
mysql_query("INSERT INTO threads (headline, text, date, forum_id, user_id)
VALUES ('$headline', '$text', NOW(), '$_POST[forum_id]', '$user[id]')");
header("Location: /thread/".mysql_insert_id()."");
}
}
How can I fix this?
Upvotes: 1
Views: 1606
Reputation:
trim()
the text inputs. You can do that easily like this:
// get input vars and trim space
$callback = array('filter' => FILTER_CALLBACK, 'options' => 'trim');
$fields = filter_input_array(INPUT_POST, array(
'headline' => $callback,
'text' => $callback,
'forum_id' => $callback,
));
// check for empty fields by counting how many are set
if ( count($fields) != count(array_filter($fields)) ) {
// something was unset
}
Upvotes: 9
Reputation: 8813
Right after checking for a submission:
foreach ( $_POST as $key => &$value ) $value = trim($value);
edit in response to asker's comment:
Odd that it didn't work as above. Here was my exercise to confirm it would.
tbramble@wayfarer:~$ php -a
Interactive shell
php > $arr = array('one',' two', ' three ');
php > print_r($arr);
Array
(
[0] => one
[1] => two
[2] => three
)
php > foreach ( $arr as $key => &$value ) $value = trim($value);
php > print_r($arr);
Array
(
[0] => one
[1] => two
[2] => three
)
Must have something to do with working on a superglobal instead of a normal array.
Upvotes: -1
Reputation: 166076
The empty function checks for variables that meet a set criteria, from the manual
Returns FALSE if var has a non-empty and non-zero value.
The following things are considered to be empty:
"" (an empty string)
0 (0 as an integer)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
var $var; (a variable declared, but without a value in a class)
Your $_POST fields actually contain something like this
" ";
This isn't and empty string, but a string that's filled with whitespace characters.
Before using empty(), trim() the white-space from your POSTed values
$trimmed_post = array();
foreach($_POST as $key=>$value){
$trimmed_post[$key] = $value;
}
if(!empty($trimmed_post['headline'])){
//...
}
You don't need to put the new values into a new array, but I'm not a big fan of changing what's in the auto-generated superglobals.
One final note, you can't do something like this
if(!empty(trim($_POST['headline']))){
//...
}
because the empty function expects to be passed an actual variable. You could do something like this instead
if('' != trim($_POST['headline'])){
//...
}
This is probably the best approach to take. You reduce the number of functions that you need to call, users can post entries with a value of 0, and the code is more explicit about what it does. Another form you'll see is
if(trim($_POST['headline'])){
}
This works because PHP evaluates an empty string ('') as false, and a non empty string as true. I tend to avoid this form because I've found a lot of PHP bugs crop up around misunderstandings on how the equality operators get boolean values out of certain types. Being explicit helps reduce occurrences of these types of bugs.
Upvotes: 3
Reputation: 150789
I agree that trimming is the way to go. Here's a much easier way to go about it:
$_POST = array_map('trim', $_POST);
Upvotes: 1
Reputation: 1795
I trim every $_GET
& $_POST
variable as soon as the app starts. try something like this:
function trimArray(&$array) {
if (empty($array)) {
return;
}
foreach ($array as $k => $v) {
if (! is_array($v)) {
$array[$k] = trim($v);
} else {
trimArray($v);
}
}
}
if (! empty($_GET)) {
trimArray($_GET);
}
if (! empty($_POST)) {
trimArray($_POST);
}
Upvotes: -1
Reputation: 48369
Just a quick note: You're injecting the value of $_POST['forum_id']
into the SQL; that's not a good idea, since a user could manipulate that value as desired, even if it is coming from a hidden field. It would be wise to escape the value, or at least pass it through intval()
and ensure it's an integer (assuming integral post identifiers).
Upvotes: 1
Reputation: 70001
Try
if (!empty($_POST['headline']) && !empty($_POST['text']) &&
!empty($_POST['forum_id']))
For the logic.
You'd have to switch it around though.
UPDATE to clarify:
if (isset($_POST['submit']) && !empty($_POST['headline']) &&
!empty($_POST['text']) && !empty($_POST['forum_id'])) {
$headline = mysql_real_escape_string($_POST['headline']);
$text = mysql_real_escape_string($_POST['text']);
mysql_query("INSERT INTO threads (headline, text, date, forum_id, user_id)
VALUES ('$headline', '$text', NOW(), '$_POST[forum_id]', '$user[id]')");
header("Location: /thread/".mysql_insert_id()."");
}
else
{
header("Refresh: 2; url=/add-thread");
die('You must fill out every field.');
}
}
Upvotes: 0