Log in

View Full Version : How do get around 0 being treated as a null value?



toe_head2001
04-05-2009, 09:23 PM
I have a form input in which I would like to submit the the value of 0, but it being treated as a null value. I don't want to have to use 00.

I'm using this code, what changes do I need to make?


if (!$_POST['description'] | !$_POST['id']) {
die('You did not complete all of the required fields');
}

Schmoopy
04-05-2009, 10:02 PM
if (!$_POST['description'] || !$_POST['id'] && $_POST['id'] != '0') {
die('You did not complete all of the required fields');
}

Treats 0 as a literal string, there may be other ways of doing it but this seems to work.

Twey
04-05-2009, 11:00 PM
The string '0' is falsy in PHP: that is to say, '0' == false. Nobody knows quite why; it's counterintuitive and frankly stupid, but hey, it's PHP: we're used to it.

Anyway, the proper way around it, in this case, is to use the empty (http://www.php.net/empty)() function:


if (empty($_POST['description']) || empty($_POST['id']))
die('You did not complete all the required fields.');

Generally, if you need to check two values, use ===, the equality operator, rather than ==, the type-converting equality operator. Use == only if you've carefully considered all the possible types of both sides and explicitly want to allow them all.

Something else to watch out for is that || (logical OR) is not the same as | (bitwise OR). In many situations, via several type coercions, bitwise operators will act in a similar manner to their logical counterparts, but bitwise operators do not short-circuit, so they will often exhibit worse performance, and additionally in some cases they may exhibit vastly different behaviour: '8' & '4' is falsy, even though '8' && '4' is true.

Schmoopy
04-05-2009, 11:31 PM
I can't believe I'm saying this, but for once I think you're wrong :eek:

I've used empty() before and have known it to take "0" as a null string, as it says in the php manual:


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)

I also tested the code and as I expected, inputting 0 in a field returned "You did not complete all the required fields".

I'm pretty sure the way I've done it isn't the most efficient either, but the way you have proposed doesn't seem to work at all. Am I missing something?

Twey
04-06-2009, 12:30 AM
Ah, it seems you're right — that was added in PHP4. I should have read the fine manual before commenting :)

The other option here, then, would be:
if (@$_POST['description'] === NULL || @$_POST['id'] === NULL)

Something peculiar happened when I was trying to test out empty():

php > print empty("");
php > print empty("0") ? "Yes" : "No";
php > print (empty("0") ? "Yes" : "No");
php > print "huh?";
huh?
php > print true ? "yes" : "no";
yes
php > print empty("0") ? "Yes" : "No";
php > error_reporting(E_ALL);
php > print empty("0") ? "Yes" : "No";
php > echo("Hi");
Hi
php > echo(true ? "Yes" : "No");
Yes
php > echo(empty(0) ? "Yes" : "No");
php > It seems I can't print the value of an expression containing empty(). Maybe I'm missing something here.

CrazyChop
04-06-2009, 11:18 AM
Ah, it seems you're right — that was added in PHP4. I should have read the fine manual before commenting :)

It seems I can't print the value of an expression containing empty(). Maybe I'm missing something here.

there is also the is_number() if you wish to check whether it is NULL or what, but === is the way to go.

Re: empty() -- maybe it only works on variables and not expression?

Schmoopy
04-06-2009, 12:00 PM
I don't think $variable === null works either, I just tried it and it didn't stop anything, if I put in a 0 it didn't pick up on it, if I left it blank it did the same thing. There must be a better way to do this, but the null way doesn't seem to work at all.

Edit:



if ($_POST['description'] === '' || $_POST['id'] === '')


This seems to work too, allows 0.

Twey
04-06-2009, 01:08 PM
Er, yes, of course — I was thinking they'd be undefined, but of course they're only actually likely to be empty strings. That's what you want.

CrazyChop
04-06-2009, 02:17 PM
I don't think $variable === null works either, I just tried it and it didn't stop anything, if I put in a 0 it didn't pick up on it, if I left it blank it did the same thing. There must be a better way to do this, but the null way doesn't seem to work at all.

Edit:



if ($_POST['description'] === '' || $_POST['id'] === '')


This seems to work too, allows 0.



if (isset($_POST['id'] && $_POST['id'] === null)


For cases when id is not set (hey, that may happen...what if the user types in the URL directly?)

Anothing to try may be



$_POST['id'] = intval($_POST['id']);

// If isset code here


Typically, it's better to leave a variable undefined then to have it points to empty for query string, IMHO.

Nile
04-06-2009, 02:22 PM
It seems I can't print the value of an expression containing empty(). Maybe I'm missing something here.

From what I understand, it appears empty() cant take direct input. Even though it should be a mixed var. Hmm... Maybe its being fixed for PHP 6.

Twey
04-06-2009, 03:40 PM
That would make some sense, but it seems it should trigger an error or at least a warning, rather than just ignoring the whole statement.

CrazyChop
04-06-2009, 03:58 PM
That would make some sense, but it seems it should trigger an error or at least a warning, rather than just ignoring the whole statement.

By default, PHP is rather lenient. If it comes across a variable not declared before and is being used, it will create it on the spot. To catch those errors, put this at the start of any PHP script



error_reporting(E_ALL);


In fact, this is my SOP. Helps to catch a lot of bugs due to mis-spelling and such.

Twey
04-06-2009, 06:45 PM
I was not using any variables, and I had turned on E_ALL error-reporting (as you can see from the transcript of the session I posted). I agree that it is usually a good idea to turn on E_ALL in new scripts.

JasonDFR
04-06-2009, 08:09 PM
You have to feed empty() a variable. Constants cause parse errors. I don't know why you weren't getting errors Twey.


php > echo empty(0) ? 'yes' : 'no';

Parse error: syntax error, unexpected T_LNUMBER, expecting T_STRING or T_VARIABLE or '$' in php shell code on line 1
php > print empty(0) ? 'yes' : 'no';

Parse error: syntax error, unexpected T_LNUMBER, expecting T_STRING or T_VARIABLE or '$' in php shell code on line 1
php > $var = 0;

php > print empty($var) ? 'yes' : 'no';
yes
php >


My recommendation for the OP is:


if ( $_POST['description'] == '' || !is_numeric($_POST['id']) ) {
die('You did not complete all of the required fields');
}

Twey
04-06-2009, 09:12 PM
is_numeric() is good, but I stand by my recommendation of === for the former.

JasonDFR
04-07-2009, 05:20 AM
$_POST['description'] = '';
$_POST['id'] = 100;

if ( $_POST['description'] === NULL || !is_numeric($_POST['id']) ) {
die('You did not complete all of the required fields');
}

The problem with === NULL is that it doesn't test for an empty string. If the POST variable is set, which if the form was submitted, it will be, NULL won't filter anything.

Schmoopy
04-07-2009, 10:13 AM
I think he was in favour of:



if ( $_POST['description'] === '' || !is_numeric($_POST['id']) ) {
die('You did not complete all of the required fields');
}


Not:



if ( $_POST['description'] === NULL || !is_numeric($_POST['id']) ) {
die('You did not complete all of the required fields');
}

JasonDFR
04-07-2009, 06:07 PM
I think he was in favour of:



if ( $_POST['description'] === '' || !is_numeric($_POST['id']) ) {
die('You did not complete all of the required fields');
}


Not:



if ( $_POST['description'] === NULL || !is_numeric($_POST['id']) ) {
die('You did not complete all of the required fields');
}


Oh. Ok.

What is the difference between =='' and ===''. Is 0 =='' true, whereas 0 ==='' not true? In the case of posted variables which I think are always going to be strings, why does === make a difference?

Twey
04-08-2009, 11:23 AM
Well, for example, '0' == false. Strings can be coerced too.

JasonDFR
04-08-2009, 11:54 AM
I'm sorry Twey, please bare with me.

I am not seeing a difference:


<?php

$_POST['description'] = '0';
$_POST['id'] = 100;

// BETWEEN

if ( $_POST['description'] === '' || !is_numeric($_POST['id']) ) {
die('You did not complete all of the required fields');
}

// AND

if ( $_POST['description'] == '' || !is_numeric($_POST['id']) ) {
die('You did not complete all of the required fields');
}

exit;

What am I missing? Or is it that you are saying since we know the $_POST variable is a string we should explicitly test for the value and type, hence === '' , where '' is an empty string ?

Twey
04-08-2009, 12:11 PM
In this case (comparing a known string with '') there isn't much difference (although it could well be more efficient) — it's just good practice.