Link to home
Start Free TrialLog in
Avatar of Crazy Horse
Crazy HorseFlag for South Africa

asked on

if(empty) validation fires when trying to select 0 from select list

I have a simple select list and just want to make sure that if nothing is selected and it is left on it's default of "Please select", then an error message will display. This works fine but when I select zero then the error still fires. 0 should be an acceptable option.

 
<select class="form-control" name="actual">
	<option value="">Please select</option>
	<option value="0">0</option>
	<option value="1">1</option>
	<option value="2">2</option>
	<option value="3">3</option>
	<option value="4">4</option>
	<option value="5">5</option>
	<option value="6">6</option>
	<option value="7">7</option>
	<option value="8">8</option>
	<option value="9">9</option>
	<option value="10">10</option>
	<option value="11">11</option>
	<option value="12">12</option>
	<option value="13">13</option>
	<option value="14">14</option>
	<option value="15">15</option>
</select>

Open in new window


		if(empty($_POST['actual'])) {
			
			$message .= "Please enter your target <br/>";
		}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Dmitrii
Dmitrii
Flag of Russian Federation image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Crazy Horse

ASKER

I have set the column in the database as an integer. So, will this:

<option value="zero">0</option>

Open in new window


enter a "0" in the database?
(!isset($_POST

Open in new window


did not work..
No, you need an additional translation like this:
if ($my_variable == "zero"){
              $my_variable=0;
              }

Open in new window

Hmm. That seems like a long way around. I have an idea. What do you think about this?

if(strlen($_POST['actual']) < 1) {

Open in new window

<?php
$actual = isset($_POST['actual']) ? $_POST['actual'] : '';
if ($actual != '') {
   echo "Good";
}
else {
	echo "Bad";
}?>

<form method="post">

<select class="form-control" name="actual">
	<option value="">Please select</option>
	<option value="0">0</option>
	<option value="1">1</option>
	<option value="2">2</option>
	<option value="3">3</option>
	<option value="4">4</option>
	<option value="5">5</option>
	<option value="6">6</option>
	<option value="7">7</option>
	<option value="8">8</option>
	<option value="9">9</option>
	<option value="10">10</option>
	<option value="11">11</option>
	<option value="12">12</option>
	<option value="13">13</option>
	<option value="14">14</option>
	<option value="15">15</option>
</select>

<input type="submit" />
</form>

Open in new window

Working sample here
So, will this:

<option value="zero">0</option>

enter a "0" in the database?
Not by itself, but it will put the word "zero" into the request variables if it is the selected option.
I never use 'empty' (don't remember why) but I do use a POST filter and I usually use '-' as the default value for 'select statements.  'isset' won't consider any of those values to be Not Set.  This is an example of what I normally use:
if (!isset($_POST['name']))  $name = ''; else $name = $_POST['name'];

Open in new window

@Dave: New syntax (sugar only) for PHP 7.  "Null coalescing operator" simplifies a common task and it's chainable -- the first isset() value will be used to assign the variable.
https://wiki.php.net/rfc/isset_ternary
http://php.net/manual/en/migration70.new-features.php
$name = $_POST['name'] ?? '';

Open in new window

Note that empty() is loosely typed, but isset() has no understanding of type.  A value of zero ('0') is TRUE for empty().
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Please note that all PHP pages that receive form values, either GET or POST, can expect spam, sometimes a lot of automated spam.  Last month a spammer found a form that I had not protected properly and POSTed 754 times to it before the hosting company blocked them.  My customer wasn't happy with receiving 754 spam emails.  They were all intended to cause SQL injection.  They didn't, I wasn't that dumb.

Normally on these pages I check the referrer which works almost all of the time because spammers are lazy.  I had forgotten to do that on that page.  Using substr() to limit the size of the data helps too.
@Julian: for you, Dave, me, this is not complicated, and there are lots of ways to get to a good solution.  But if you're new to PHP you might not know that zero, whether expressed as an integer 0 or as a string '0', is one of the values that evaluates boolean TRUE for empty().  And sometimes (perish the thought) a new PHP programmer might copy some code without looking up the function reference descriptions on PHP.net.  So the new-to-PHP programmer might not come across the explanation of the multi-layered meaning of PHP empty().  And there might be some assumptions that are wrong or incomplete.

When I'm in the classroom, I call this sort of understanding the "apple pie problem."  You have seen an apple pie, and you smelled it and tasted it.  And you love it!  Then your friend brings you a bushel of apples and says, "Let's make an apple pie."  You would love to make an apple pie -- one that smelled and tasted wonderful, but you can't because you're ignorant of the processes and additional ingredients that you need to make the pie, and you don't even know that you're missing the important information.  

Your first try might be to put all the apples into the oven and see what you get.  This is sort of like copying code without understanding the code.  The outcome is not usually good.  Burnt apples, wasted time, brown sadness mess, tears.

So you pick yourself up.  To fill in the missing information you turn to a recipe.  And that recipe calls for a crust, so you need another recipe.  It becomes a major knowledge-building moment.  For those new to PHP, a basic part of that knowledge-building moment is reading the function reference page for every function that is new or even slightly unfamiliar.  Never copy code you don't understand!

I could not work without a browser window open to the PHP.net function reference.  There is just too much to memorize in a language with 1,500+ functions.  So I use and recommend the online man pages.
I meant the solutions being offered. The principle that needs to be conveyed in addition to the falsy / truthy is that the core of the problem here is more to do with how to distinguish between a default value and non-existence.

For the purposes of the required outcome these two are the same - all that is needed is some way to elegantly determine which.

The solution is to check for existence and default the value to the <select> default if the POST variable does not exist. I think we have covered in detail the issues of 0,'',false and null.

The point I was trying to make was based on the author deviating from his original post to start using values like "zero" - my intent was to illustrate that his original approach was mostly there all he needed to was add the line for the extraction of the POST and modify the line to test this value for the default.
So if you want '0' to be an acceptable value, you can't use 'empty()'.  You can use 'isset()' as I have shown because all GET and POST values are received as text.  They are easily and often automatically converted into numbers by both PHP and MySQL.
Wow, talk about getting more than I bargained for. I did not expect this much feedback, so thanks to all who assisted!

EE, are you listening? I am AGAIN in the situation where I just want to give everyone the same level of acceptance/best answer because everyone made a valuable contribution and I now have to pick a "best" answer.

I'll have to have a few pints after work and then just click wherever my finger takes me :-P
Further to Dave's point about ..."all GET and POST values are received as text."  Except for radio buttons and check boxes, which might or might not be received at all.  There is no end to all of the rabbit holes that PHP has created for us!
greetings black sulfer,  I have used the test for strlen($_POST['input']) to good effect, At first I thought it would throug a "warning" if the $_POST['input']) was not defined (not set), but it did not, it returns 0.

you may try -
if(!strlen($_POST['actual']) ){
  $message .= "Please enter your target <br/>";
  }

if you only need to detect a not set or an empty string, ,
but please consider better filtering as  Dave Baldwin suggested, the spammers are alive, creative and persistent?
Thanks Slick812. I would hope that spammers won't be an issue because this is all happening within a password protected area. But I don't want to assume anything....
PHP strlen() will throw a Notice, not a Warning, if the variable or array index is not set.  If error_reporting(E_ALL) is on, you will see the Notice.