14

I'm getting a string from a $_GET and I want to test if it could be a boolean, before I use it for a part of a mysql query. Is there a better way of doing it than:

function checkBool($string){
    $string = strtolower($string);
    if ($string == "true" || $string == "false" || 
        $string == "1" || $string == "0"){
        return true;
    }
    else {
        return false;
    }
}

if (checkBool($_GET['male'])){
    $result = mysql_query(
        "SELECT * FROM my_table " .
        "WHERE male='".$_GET['male']."'") or die(mysql_error());
}
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
DexCurl
  • 1,683
  • 5
  • 26
  • 38
  • This won't work anyway. What is your column type for `male`? The MySQL boolean type is really just a tinyint(1) so if it's that then you should only check for 1s or 0s. If you're using char/varchar and have previously set it to "true" then comparing it with "yes" or "1" will still not match. – daiscog Nov 25 '11 at 18:01
  • point taken for checking yes and no, edited my snippet accordingly. Column type is indeed tinyint(1)! so true, false, 1 and 0 is what I need to check for – DexCurl Nov 25 '11 at 18:12
  • @DexCurl, This doesn't really change anything. You'll still have to use your own function, rewrited as I answered below. – Shoe Nov 25 '11 at 18:16
  • Checking for string equivalency won't work, though. Your SQL puts $_GET['male'] inside quote marks, so if $_GET['male'] was "true" you'd get `SELECT * FROM my_table WHERE male='true'`. This will actually return rows where male=0 because MySQL tries to convert the STRING "true" to a number but can't so it gives it the value 0. Take out the single quotes and it works as expected. – daiscog Nov 25 '11 at 18:17
  • @daiscog, I believe you have NOT got the point of the question. – Shoe Nov 25 '11 at 18:19
  • @daiscog testing this now and seemingly working perfectly – DexCurl Nov 25 '11 at 18:26
  • @JeffPigarelli I do understand the question, just pointing out that `SELECT * FROM my_table WHERE male='true'` might not behave as you'd expect and `SELECT * FROM my_table WHERE male=true` is what you need. – daiscog Nov 25 '11 at 18:33
  • @DexCurl `SELECT * FROM my_table WHERE male='true'` didn't work when I tried it. – daiscog Nov 25 '11 at 18:34

8 Answers8

20

You can either use is_bool() or as suggested on php.net:

<?php
$myString = "On";
$b = filter_var($myString, FILTER_VALIDATE_BOOLEAN);
?>

http://php.net/manual/en/function.is-bool.php

The latter one will accept strings like "on" and "yes" as true as well.

zrvan
  • 7,533
  • 1
  • 22
  • 23
  • 1
    +1 i've been using php for years and i've never heard of this 'filter_var' function. cool! Although you have to be using php >= 5.2. thanks! – Flukey Nov 25 '11 at 18:03
  • 1
    This doesn't really solve anything. "False" will return false in both `is_bool()` and `$b`. – Shoe Nov 25 '11 at 18:06
  • 1
    Thanks for your answer zrvan! is_bool() doesn't work with strings as tested by `var_dump(is_bool("true"));` and filter_var works nicely to transform something into a boolean answer, but I needed something to check if string is a boolean first – DexCurl Nov 25 '11 at 18:09
  • 1
    `is_bool()` does work with strings: it always returns FALSE, which is the correct answer since strings are strings, not booleans ;-P – Álvaro González Nov 25 '11 at 18:42
  • @Shoe see my [answer](http://stackoverflow.com/a/35310203/2459228) for how `filter_var()` can be used to validate strings like "False" and be a viable solution to the problem. – Magnar Myrtveit Feb 10 '16 at 09:16
12

There's, by the way, a cleaner way of writing it:

function checkBool($string){
    $string = strtolower($string);
    return (in_array($string, array("true", "false", "1", "0", "yes", "no"), true));
}

But yes. The one you wrote down is the only way.

Shoe
  • 74,840
  • 36
  • 166
  • 272
  • Thanks for your Jeff, very nice way of doing it. Greatly appreciated! – DexCurl Nov 25 '11 at 18:16
  • 2
    This might look neater but involves more overhead for PHP. It has to create an array, store it in the heap, then call another function which does the comparison. The original function is more efficient. – daiscog Nov 25 '11 at 18:18
  • 3
    @daiscog, seriously? How much does it cost more? 0.0000000000000000000000000001 nanosecond to perform 123456789 calls to that function? It will probably be near 3 minutes the time you'll need to figure out what that original function does. – Shoe Nov 25 '11 at 18:20
  • Haha, yeah I have this discussion a lot. But I think the original function is pretty clear and I'm one of the "every clock cycle counts" brigade, I'm afraid. Old fashioned, I suppose, but I think it all adds up, especially in big applications. – daiscog Nov 25 '11 at 18:31
  • See [my answer to another question](http://stackoverflow.com/questions/4775294/parsing-a-string-into-a-boolean-value-in-php/11497131#11497131) for a more flexible (yet more verbose) solution. DexCurl [should really be using parameterized queries](http://stackoverflow.com/questions/60174/best-way-to-prevent-sql-injection-in-php), anyway. – Matt Kantor Jul 16 '12 at 01:34
  • The call to in_array() should include `true` for the third parameter to do a strict comparison if you want to NOT have "1.0" or "0.0" treated as a bool. – Justin Schwartzenberger May 04 '15 at 16:24
5

If you use the flag FILTER_NULL_ON_FAILURE, filter_var() will work nicely:

function CheckBool($Value) {
  return null !== filter_var($Value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
}
Magnar Myrtveit
  • 2,432
  • 3
  • 30
  • 51
2

Boolean variables contain true or false values. To test if string could be boolean, different approaches can be used:

  • is_bool($var): The function is_bool() checks whether a variable’s type is Boolean and returns true or false.

  • Comparison using “===” or ($var===true || $var===false): If you compare the variable with the operator “===” with true and false and if it is identical to one of the values, then it is a boolean value. Since the functionality of is_bool($var) is same, the function should be preferred.

  • Comparison using “==” or ($var == true || $var == false): If you use “==” as an operator instead, the test is more tolerant. For example, 0(integer) or “”(empty string) would also result in a Boolean value.

Read more in How to check if a variable is a Boolean in PHP?

thomas
  • 785
  • 8
  • 7
2

No you got it, there isn't anything more you can do, you got all possible values that would normally be considered as true or false and you're doing the comparison the right way, you COULD optimize it using an IN_ARRAY maybe, but even so, i find this version quite good already.

Mathieu Dumoulin
  • 12,126
  • 7
  • 43
  • 71
1

Your checkBool() is quite right, IMHO, though there's a problem with the resulting SQL code. You can use TRUE and FALSE, but you must be aware that they aren't strings:

The constants TRUE and FALSE evaluate to 1 and 0, respectively. The constant names can be written in any lettercase.

So where it says this:

"SELECT * FROM my_table WHERE male='".$_GET['male']."'"

... it should say this:

'SELECT * FROM my_table WHERE male='.$_GET['male']

It'd feel better if checkBool() was actually convertToBool() and you would feed your query with its result value rather than the original $_GET, but your code is not really wrong.

BTW, I'm assuming that you are using a BOOL column type. This is what the manual says:

These types are synonyms for TINYINT(1). A value of zero is considered false. Nonzero values are considered true

Of course, it's up to you whether to use BOOL, ENUM, CHAR(1) or anything else, as well as whether to accept 33 as synonym for TRUE ;-)

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
0

For what it's worth, if you really wanted to accept "yes" or "no" as valid input from the user, then I'd do something like this:

function toBoolean($string){
    $string = strtolower($string);
    if ($string == "true" || $string == "1"|| $string == "yes" )
        return true;
    elseif ($string == "false" || $string == "0" || $string == "no")
        return false;
    else
        throw new Exception("You did not submit a valid value, you naughty boy");
}

try {
    $query = "SELECT * FROM my_table WHERE male=" . (toBoolean($_GET['male']) ? "1" : "0" );
    $result = mysql_query($query) or die(mysql_error());
} catch (Exception $e) {
    // handle bad user input here
}
daiscog
  • 11,441
  • 6
  • 50
  • 62
  • What about fetching all this instructions... "every clock cycle counts" brigade... ahah – Shoe Nov 25 '11 at 18:47
-1

You can use is_bool to test your string:

if(is_bool($val)){
  // is boolean
}else{
  // not a boolean
}
Ikhlak S.
  • 8,578
  • 10
  • 57
  • 77
  • 3
    `is_bool` will return `true` only if `$val` is "pure" `true` or `false`, but it will return `false` for `"true"` and `"false"` strings. – Wesley Gonçalves Feb 20 '19 at 13:04