Detect null column value in PHP mysqli - php

I have a php project that uses mysqli to query a database. Some of the columns in this database can be null. I have code that looks something like this:
$query = "...";
$result = $DB->query($query);
$row = $result->fetch_assoc();
$column = $row['mycolumn'];
If mycolumn is null, the value of $column appears to be the string, "NULL" (NOT the null value, but actually the string containing the word "NULL"). So what happens if I have columns which actually have the string "NULL" in them? How can I differentiate?
Thanks!
Josh
EDIT:
Upon closer inspection, it appears that the string is actually a 5-characters string. The first 4 characters are "NULL", but the last character is 0x0d, the carriage return. This makes it a lot easier to detect, although I'm still curious if there's a less hack-y way than just doing string comparison.

Use an if condition to check with ===
if($row['mycolumn'] === null) {
echo 'Real Null';
} elseif($row['mycolumn'] == '') {
echo 'Blank';
}

You are looking wrong way. Instead of trying to detect wrong NULL value you have to find out why it is wrong and correct it.
Neither Mysql nor mysqli would return a literal string 'NULL' for a null value.
So, you need to find your own code which converts NULL value to "NULL\n" string either at writing or reading. Are you using raw mysqli as $DB or it's a sort of abstraction class? If so - I'd say problem is there.
After that you can easily read NULL value with strict comparison === as suggested in other answers (though I am not sure about libmysql installations).

seems the column have the data type as string.
If it is string,
we can check by following
if($row['mycolumn'] == '' || is_null($row['mycolumn']))
{
echo "Coulmn is NULL value";
}
else if($row['mycolumn'] == "NULL")
{
echo "Coulmn is NULL value as string";
}

Related

PHP NULL vs 'NULL'

The code below prints out a dropdown box with the default string being --Select Status-- with a value of NULL.
print("<label>Overall Status Overwrite:</label>
<select name='case_ov_status' class='case_ov_status'>
<option selected='selected' value=NULL>--Select Status--</option>");
When the form has been submitted, it will call a function which will determine whether to dropdown box as default value, if not I will update SQL database.
However, this is where I'm confused, the if statement below will still RUN despite submitting a value of NULL.
I found out 2 hours later that by using if($case_ov_status != 'NULL') instead of if($case_ov_status != NULL) solved the problem.
if($case_ov_status != NULL){ //Still ran despite != NULL.
mysql_query("START TRANSACTION", $connection);
$sql = "Update cases set status=".$case_ov_status." Where patientid='".$patientID."' and caseid='".mysql_real_escape_string($case)."'";
$resultNew = mysql_query($sql, $connection);
This may sound really basic, but can someone explain how this works? As I am still learning..
Thanks in advance!
Please read http://php.net/manual/en/language.types.null.php
NULL is a special value to represent unallocated objects in php. "NULL" is a string literal containing the word NULL and is not the same. In PHP however you may see that it will do some type juggling with equality. For example, "" == NULL is true.
You cannot send a PHP NULL value over HTTP since everything is a string in HTTP. So your form even though you specify NULL as a value, will actually send "NULL" to the server.
value=NULL is equivalent to value="NULL". You can't submit non-string values over HTTP. Instead of value=NULL use value="" (empty string). This is falsy for php just like NULL is.
All inputs are ALWAYS represented as string data.
You just have to fill your values with correct values, it cannot be of type null, neither int or smth else.
Possible workaround for you:
Cast every input to integer, if you expect an integer. Like $id = (int) $_GET['id'] ;
Use such functions as empty(). It will return true on "0", 0, null and some other.
you have gotten confused here.
NULL != 'NULL'
The null on the left is a reserved value for a variable that has no value,
The nul on the right is a string containing the word null.
Now to get to your example provided, if you changed your if statement to != 'NULL' (with quotes) you will get your expected result.
if($case_ov_status != "NULL")
My advice however would be to set that value in the option tag to value="" or value="0" and then change your if statement to either :
if($case_ov_status != "")
if($case_ov_status != 0)
or even better
if(!empty($case_ov_status))
when user select <option selected='selected' value=NULL>--Select Status--</option>");, it returns the value you specified in value attribute. it could be 1,2,abc,..or NULL. the string NULL returns as selected value.
when you check if($case_ov_status != NULL), it says $case_ov_status is set to NULL value (that is "") or not? but obviously you need to check if selected value is NULL string. so you have to say if($case_ov_status != 'NULL')

Checking for a null value in conditional in PHP

I have found there to be multiple ways to check whether a function has correctly returned a value to the variable, for example:
Example I
$somevariable = '';
$somevariable = get_somevariable();
if ($somevariable)
{
// Do something because $somevariable is definitely not null or empty!
}
Example II
$somevariable = '';
$somevariable = get_somevariable();
if ($somevariable <> '')
{
// Do something because $somevariable is definitely not null or empty!
}
My question: what is the best practice for checking whether a variable is correct or not? Could it be different for different types of objects? For instance, if you are expecting $somevariable to be a number, would checking if it is an empty string help/post issues? What is you were to set $somevariable = 0; as its initial value?
I come from the strongly-typed world of C# so I am still trying to wrap my head around all of this.
William
It depends what you are looking for.
Check that the Variable is set:
if (isset($var))
{
echo "Var is set";
}
Checking for a number:
if (is_int($var))
{
echo "Var is a number";
}
Checking for a string:
if (is_string($var))
{
echo "var is a string";
}
Check if var contains a decimal place:
if (is_float($var))
{
echo "Var is float";
}
if you are wanting to check that the variable is not a certain type, Add: ! an exclamation mark. Example:
if (!isset($var)) // If variable is not set
{
echo "Var Is Not Set";
}
References:
http://www.php.net/manual/en/function.is-int.php
http://www.php.net/manual/en/function.is-string.php
http://www.php.net/manual/en/function.is-float.php
http://www.php.net/manual/en/function.isset.php
There is no definite answer since it depends on what the function is supposed to return, if properly documented.
For example, if the function fails by returning null, you can check using if (!is_null($retval)).
If the function fails by returning FALSE, use if ($retval !== FALSE).
If the function fails by not returning an integer value, if (is_int($retval)).
If the function fails by returning an empty string, you can use if (!empty($retval)).
and so on...
It depends on what your function may return. This kind of goes back to how to best structure functions. You should learn the PHP truth tables once and apply them. All the following things as considered falsey:
'' (empty string)
0
0.0
'0'
null
false
array() (empty array)
Everything else is truthy. If your function returns one of the above as "failed" return code and anything else as success, the most idiomatic check is:
if (!$value)
If the function may return both 0 and false (like strpos does, for example), you need to apply a more rigorous check:
if (strpos('foo', 'bar') !== false)
I'd always go with the shortest, most readable version that is not prone to false positives, which is typically if ($var)/if (!$var).
If you want to check whether is a number or not, you should make use of filter functions.
For example:
if (!filter_var($_GET['num'], FILTER_VALIDATE_INT)){
//not a number
}

Accessing psql-array directly in PHP

I am querying a psql database through PHP to get an array of boolean values where indexes are userids, e.g. userconfirm bool[]. When I do something like:
$query = "select userconfirm from calendar where id = '%s'";
$result = $this->db->query($query, 2);
var_dump($result['userconfirm']);
I get:
array(1) { [0]=> array(1) { ["userconfirm"]=> string(20) "[256:258]={t,NULL,t}" } }
Which is to say I get a string where the array should be. Ok, parsing this could probably be done, if I studied up on PHP, but this feels wrong. Surely there's a way to get the array directly?
Main question is: How do I get this array to PHP directly?
Secondary question: Is this a suitable format for keeping track of user attendance? Is there a better way?
(Re-posted from a comment by request)
Glancing at the documentation, it doesn't appear as though there's a way to directly interpolate a PostgreSQL array to an array in PHP. However, if the position of your vector represents a user id, you might be better off restructuring your data to columns with user_id and attended (the latter of which should be a boolean datatype).
PHP's native PostgreSQL driver does not support advanced data-types. In fact, it doesn't even properly support integers, booleans or anything else! (cite: As stated here under "Return Values", all values are returned as strings, NOT their correct data type: http://www.php.net/manual/en/function.pg-fetch-assoc.php)
To help battle this problem, you may want to check out PHPG, a PHP library designed to specifically transform all returned PostgreSQL values to native PHP data-types. Supports arrays for any data-type, Hstores, Geometric data-types, and more:
Numeric / Integers
If you're a numeric[] or integer[] data type which does NOT have the possibility of containing NULL values, then you can simply remove the leading and trailing curly brackets, and explode the string into an array using the comma delimiter: https://github.com/JDBurnZ/PHPG
<?php
$pg_intarr = '{1,2,3,4,5}';
$vals = substr($pg_intarr, 1, -1); // Remove curly brackets
$vals = explode(',',$vals); // Returns: array(1,2,3,4,5)
Strings
However, the problem becomes much more complex when dealing with string-based data types such as character[], character varying[] or text[] and here is why: If the value of an array contains a space or some other special character, then PostgreSQL returns that particular value encapsulated in double quotes. If the value is a single word with no special characters, then that value is returned with no quotes whatsoever.
Here is an example character varying[] value returned from PostgreSQL:
{val1,"val 2",val3,"val-4","val,4"}
The challenge here is:
Can't explicitly explode on "," because not all strings are double-quoted.
Can't explicitly explode on , because a value may contain a comma such as val,4
The only method I was able to derive after MONTHS of encountering this problem over and over again was to take the string provided by PostgreSQL, and perform a subsequent query to UNNEST the array into a result set, which is then read and transformed into a native PHP array:
$grab_vals = pg_query("SELECT UNNEST('" . pg_escape_string('{val1,"val 2",val3,"val-4","val,4"}') . "') AS value");
$grab_vals = pg_fetch_all($grab_vals);
$array_vals = array();
foreach($grab_vals as $val) {
$array_vals[] = $grab_vals['value'];
}
Booleans
In regards to boolean[] values, you could most likely take the same approach as suggested for integers. However because you also anticipate NULL values, we have the added task of mapping the string value NULL to PHP's native NULL data-type:
function pgBool2Php($string) {
if($string == 't') {
return True;
} else if($string == 'f') {
return False;
} else if($string == 'NULL') {
return Null;
} else {
raise new Exception('Mal-formed PostgreSQL Boolean encountered. Expecting value of "t", "f" or "NULL", encountered "' . $string . '"');
}
}
$pg_intarr = '{t,NULL,t,f}';
$vals = substr($pg_intarr, 1, -1); // Remove curly brackets
$vals = explode(',',$vals); // Returns: array('t','NULL','t','f')
$vals = array_map('pgBool2Php', $vals); // Returns: array(True, Null, True, False)
heres my pg_parse function on github

Determine if variable has ANY text

I would like to determine whether or not a variable has any text at all.
For instance, my current code is this:
if (is_numeric ($id))
{
//do stuff
}
else
{
// do other stuff
}
However, there is a problem if my variable contains both a string and a number
such as "you are 93 years old",
because it sees that number 93 is present and considers the variable numeric.
I want the if statement to only "do stuff" if there is absolutely no text in the variable at all.
Thanks
Try casting the value to int (or float) then compare it back to the unaltered version. They should match values (but not type)
if((int)$id == $id) {
} else {
}
another option would be to use preg_match("/^([\d.\-]+)$/", $id). This would allow you to be very specific about what characters you let $id contain. However using regexp should be considered as the final choice (for performance reasons)
if(empty($var) && $var !== "0" && $var !== 0) {
// it's really empty, not a string "0" and not a numeric 0
}
You could also check if it's not a boolean false for the sake of completeness.

Boolean issues in PHP

I have a question regarding bools in php. I have a stored mysql proc that is returning a boolean. When this value is grabbed on the php side it displays the value as being a 0 or 1. This all seems fine to me and I have read in the php manual that php will interpret a 0 or 1 as false or true at compile time but this does not seem to be the case to me. I have gone a step further and casted my returned value with (bool) but this still does not seem to work.
My if statements are not properly firing because of this. Does anyone know what is going on? Thanks for the help.
MySQL does not have a proper BOOL or BOOLEAN data types. They are declared as synonyms for TINYINT(1). Your procedure will return 0 or 1, which being on non-PHP ground will get transformed into a string in PHP land, so in PHP you have the strings '0' and '1'.
It is weird however that boolean casting does not convert them to the appropriate booleans. You may have some other bugs in your code.
Are you trying to cast the direct result from the query? Because that one is probably an array and:
var_dump((bool) array('0')); // true
Maybe this is your problem. Inspect the returned result.
It sounds like the boolean value is being returned as a string.
Try something like this:
$your_bool = $field_value === "0" ? false : true;
Using the script below. (You'll have to add HTML line break tags before the word "Boolean" inside the left quote to make the output look like my sample; when I do, Firefox interprets them, making the format look strange).
You'll see that the second line produces a null value which MySQL sees as something different from 0 or 1; for TINYINT it stores the PHP true value correctly but nothing for the PHP false, since a null value has no meaning for TINYINT.
Line four shows type casting with (int) is a way to insure that both PHP true and false are stored to MySQL TINYINT Boolean fields. Retrieving the resultant integers from MySQL into PHP variables works since integers are implicitly cast when assigned to PHP Boolean variables.
echo "Boolean true=".true;
echo "Boolean false=".false;
echo "Boolean (int)true=".(int)true;
echo "Boolean (int)false=".(int)false;
Here's the output from PHP 5.3.1 for MySQL 5.1.41:
Boolean true=1
Boolean false=
Boolean (int)true=1
Boolean (int)false=0
Oh! And PHP Boolean literals may be all lowercase or uppercase with the same result... try it yourself.
I use a helpful function "to_bool" for anything I'm not sure of the type of:
function to_bool($value, $default = false)
{
if (is_bool($value)) {
return $value;
}
if (!is_scalar($value)) {
return $default;
}
$value = strtolower($value);
if (strpos(";1;t;y;yes;on;enabled;true;", ";$value;") !== false) {
return true;
}
if (strpos(";0;f;n;no;off;disabled;false;null;;", ";$value;") !== false) {
return false;
}
return $default;
}
Then:
if (to_bool($row['result'])) { ... }

Categories