To deal with 'Boolean' values in PHP & MySQL - php

Currently I'm using Tinyint(1) to indicate Boolean values in my MySQL databases, which I really don't like that. So, how could I store and retrieve Boolean values in my MySQL databases via PHP?
How to use it in WHERE clause and how to assign the value in INSERT, UPDATE queries properly?
When I have it back on PHP, it's TRUE, true, or simply 1, if I'm gonna check that with ===?
Also did you ever had any problem when you migrating from Tinyint(1) to BOOLEAN?
Thanks in advance. :)
Update:
I know that Tinyint(1) is the same as Boolean, however I want to work on Boolean data type instead of Tinyint(1). That's why I'm asking the question.

MySQL doesn't have a boolean data type. Tinyint(1) is pretty close enough. Working with this in PHP is simple.
If (1) echo 'true'; // is the same as if (true)
// Just as
if (0) echo 'false'; // is the same as if (false)
And if you really really want a boolean value, you can do
// $mysql_data is tinyint value from db
$boolean = $mysql_data ? true : false;
// Now you have your boolean as $boolean

With booleans, don't use === FALSE - the value is already a boolean (unless the function requires you to use ===, like strpos()). The value is booleanish - it's technically an integer, but PHP is a dynamic language, so it its not a problem.
Consider preg_match() function - it returns the number of matches (integer).
Would you prefer to write that?
if (preg_match('/\bregexp?\b/', $variable) === 1)
Or that?
if (preg_match('/\bregexp?\b/', $variable))
Obviously, the way without explicit === 1 is better. You ask if it matches, not if it has 0 matches. Also, if you think that === 1 is safer, why not do === 1 === TRUE?
Of course, it's possible to convert values to booleans using (bool) or !!.
Also, in certain languages such as C or Perl, there is no difference between booleans and numbers. It just works.

<select name="can_get" id="can_get" class="form-control">
<option <?php if($can_get== "1"){ echo "selected"; } ?>
value="1">True</option>
<option <?php if($can_get== "0"){ echo "selected"; } ?>
value="0">False</option>
</select>

Related

PHP - Validate integer with filter_var() function

I see everywhere on the web that I should write something like this if I want to use the filter_var() function to validate an integer:
if (filter_var($int, FILTER_VALIDATE_INT) !== false){
echo 'Integer ok';
}else{
echo 'Not an integer';
}
From what I know, the expression filter_var($int, FILTER_VALIDATE_INT) return false if the content of $int is not evaluated as an integer or return the integer inside $int.
As any integer is then evaluated is true by the PHP (except for 0 of course), I would like to know the concrete difference when doing this:
if (filter_var($int, FILTER_VALIDATE_INT) !== false)
Or this:
if (filter_var($int, FILTER_VALIDATE_INT) == true)
For which values do these 2 expressions send different results?
I also have another question: if my variable $int contains the boolean true, in any case the result will be 'Integer ok' it seems. Are we obliged to isolate this case? Because everyone talks a lot about the "number begin by 0" case but not about this one...
Thank you!
Edit: Please do not suggest me to use other methods to validate an integer, I do not want to use other methods. As a matter of facts, I want to learn how PHP really works in depth. That is why I am wondering on this case of always seeing "!==false" and never simply "==true"
Also you can use ctype_digit(), try this:
if (!ctype_digit($int)) {
echo 'Not an integer';
} else {
echo 'Integer ok';
}
The difference is that checking for false will still work when the integer is 0, as you already pointed out, whereas checking for true you would then have to make an additional check for 0.
A boolean value of true will return as a valid int with a value of 1, as noted in this comment on the PHP manual page for the filters.
You can easily test this for yourself by printing out the results of various values passed through the filter.

TINYINT (0, 1) for boolean values in MySQL

as the title states ,TINYINT (0, 1) for boolean values in MySQL return true and false value ,,but i want yes and no value when i retrieve TINYINT (0, 1) values from database. is it possible??
Use IF:
SELECT IF(bool_value, 'yes', 'no') as string_value...
tinyint doesnt return true or false. It returns 0 or 1. If you want yes and no, you need to specify that yourself:
if($return == 0) {
return "no";
} else {
return "yes";
}
Yes, it is possible. One way is to add CASE to it:
SELECT
CASE
WHEN value = true THEN 'yes'
ELSE 'no'
END
FROM
`table`;
Another one, as Max suggested, add IF option.
Wanting "yes" and "no" sounds like it's for display purposes, and how you choose to format data from your database/models for display should be in your view oriented code and not the database schema nor the query logic, though there are valid exceptions to the latter. Aside from considerations such as whether "first name" and "last name" as separate items could be useful rather than a single "name" field, decisions about database structure should be based on what you need to store and how different data items relate to each other, not on how data is going to look once retrieved. Particularly as you're using a framework, this should be straightforward.
That said, you could use an enum type instead, defining the enum as enum('no','yes'), though cake may still not have support for enums. You can then get and set string values or numeric ones (1 and 2, or subtract 1 to get 0 and 1). Overall though, tinyint with values 0 and 1 is probably preferable as it's conventional and less likely to lead to mistakes/bugs now or in the future.
Use AppModel::afterFind
http://book.cakephp.org/2.0/en/models/callback-methods.html#afterfind
public function afterFind($results, $primary = false) {
foreach ($results as $index => $row) {
if (isset($row[$this->alias]['yes_or_no'])) {
$results[$index][$this->alias]['yes_or_no'] = $row[$this->alias]['yes_or_no'] ? 'yes' : 'no';
}
}
return $results;
}

Detect null column value in PHP mysqli

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";
}

In PHP, can I differentiate the result of intval(null) from intval("0")?

I get input values via POST, some of them might be ID's referring to other things, and some start at 0. When choosing something with ID 0, or something without a value, is there a method like intval() that returns something more helpful than 0 on failure to parse? Or can I somehow differentiate the result of intval() from the failure to parse?
Example:
echo intval(null); // 0
echo intval("0"); // 0
You can use the filter_var() function to determine the difference:
filter_var(null, FILTER_VALIDATE_INT);
// false
filter_var('0', FILTER_VALIDATE_INT);
// int(0)
You can also add flags to specifically accept hexadecimal and octal values, but I wouldn't recommend that for your case.
Btw, in the more likely case that the variable comes from $_POST, you can also use filter_input():
if (is_int($nr = filter_input(INPUT_POST, 'nr', FILTER_VALIDATE_INT))) {
// $nr contains an integer
}
The reason I'm using is_int() on the result of filter_input is because when nothing is posted, null is returned; using is_int() guards against this issue.
Edit
If the question is really just about null vs '0' you can just compare $var !== null:
if (!is_null($var)) {
// $var is definitely not null
// but it might also be an object, string, integer, float even, etc.
}
You could first check if its a number:
is_numeric($val);
Ok, now go for the solution.
preg_match('/^\d+$/','0') //is true
preg_match('/^\d+$/',NULL) //is false

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