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

LVL 1
Black SulfurAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DmitriiconsultantCommented:
PHP manual (http://php.net/EMPTY) states:
The following things are considered to be empty:

   
  •   "" (an empty string)
  • 0 (0 as an integer)
  •    0.0 (0 as a float)
  •    "0" (0 as a string)
  •    NULL
  •    FALSE
  •    array() (an empty array)
  •    $var; (a variable declared, but without a value)

You can use something like
<option value="zero">0</option>

Open in new window

or use !isset() instead of empty()
1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Black SulfurAuthor Commented:
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?
0
Black SulfurAuthor Commented:
(!isset($_POST

Open in new window


did not work..
0
Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

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

Open in new window

0
Black SulfurAuthor Commented:
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

0
Julian HansenCommented:
<?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
0
Ray PaseurCommented:
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.
0
Dave BaldwinFixer of ProblemsCommented:
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

0
Ray PaseurCommented:
@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().
0
Dave BaldwinFixer of ProblemsCommented:
What???  Learn something New???  I'm lucky that I've been able to get my customers up to PHP 5.4 and 5.5.  And that was only because Paypal and others won't work with PHP 5.3 and below.  And since I'm using 'isset' on POST and GET values, it only has to 'understand' text because that's all you get with those.

I have hundreds, maybe thousands of lines like my example.  Although on newer ones I also limit the size with a substr() statement.
if (!isset($_POST["appEmail"])) $appEmail = ''; else $appEmail = substr($_POST["appEmail"],0,64);

Open in new window

1
Ray PaseurCommented:
Here's an example suitable to the Author's question.  Remove comment markers on line 27 before flight with PHP7 :-)
https://iconoun.com/demo/temp_black_sulfur.php
<?php // demo/black_sulfur.php
/**
 * https://www.experts-exchange.com/questions/29010971/if-empty-validation-fires-when-trying-to-select-0-from-select-list.html
 *
 * http://php.net/manual/en/migration70.new-features.php
 */
error_reporting(E_ALL);


if (!empty($_POST))
{
    // PHP < 7
    if (isset($_POST['actual']))
    {
        if ($_POST['actual'] == 'choose')
        {
            $actual = 'NOTHING';
        }
        else
        {
            $actual = $_POST['actual'];
        }
    }


    // PHP 7+ IS MUCH SIMPLER SYTAX
    // $actual = $_POST['actual'] ?? 'NOTHING';

    echo PHP_EOL . "YOU CHOSE $actual";

}


$form = <<<EOD
<form method="post">
<select class="form-control" name="actual">
	<option value="choose">Please select</option>
	<option value="0">0</option>
	<option value="1">1</option>
	<option value="2">2</option>
</select>
<input type="submit" name="submit" />
</form>
EOD;

echo $form;

Open in new window

The value zero or the string zero is kind of a unique case for PHP.  Every PHP programmer who ever achieves anything of value memorizes these pages:
http://php.net/manual/en/types.comparisons.php
http://php.net/manual/en/language.types.type-juggling.php
http://php.net/manual/en/language.types.string.php#language.types.string.conversion
0
Julian HansenCommented:
Not sure why this has become so complicated - the solution is simple. If the POST value exists set your variable to it otherwise set the variable to the SAME value as the default option in the <select> - then all you have to do is check for the default value in the select.
From OP
<select class="form-control" name="actual">
	<option value="">Please select</option>

Open in new window

// PHP 7+ IS MUCH SIMPLER SYTAX
$actual = $_POST['actual'] ?? '';

Open in new window

//PHP < 7
$actual = isset($_POST['actual']) ? $_POST['actual'] : '';

Open in new window

Then do the test for the default value
if ($actual !== '') {
}

Open in new window

0
Dave BaldwinFixer of ProblemsCommented:
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.
1
Ray PaseurCommented:
@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.
1
Julian HansenCommented:
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.
0
Dave BaldwinFixer of ProblemsCommented:
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.
1
Black SulfurAuthor Commented:
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
1
Ray PaseurCommented:
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!
0
Slick812Commented:
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?
0
Black SulfurAuthor Commented:
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....
0
Ray PaseurCommented:
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.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.