143

Today I was playing with PHP, and I discovered that the string values "true" and "false" are not correctly parsed to boolean in a condition, for example considering the following function:

function isBoolean($value) {
   if ($value) {
      return true;
   } else {
      return false;
   }
}

If I execute:

isBoolean("true") // Returns true
isBoolean("") // Returns false
isBoolean("false") // Returns true, instead of false
isBoolean("asd") // Returns true, instead of false

It only seems to work with "1" and "0" values:

isBoolean("1") // Returns true
isBoolean("0") // Returns false

Is there a native function in PHP to parse "true" and "false" strings into boolean?

Mark
  • 67,098
  • 47
  • 117
  • 162
  • In your code, `isBoolean("")` should return false. – BoltClock Jan 23 '11 at 17:47
  • 1
    PHP doesn't *think* about what string says, "false" is just five characters that mean nothing. They are *something* though, so the boolean value evaluates to `true` even though to a human reader, it would seem more intuitive that it meant `FALSE`. – zeel Aug 30 '16 at 17:26

8 Answers8

465

There is a native PHP method of doing this which uses PHP's filter_var method:

$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN);

According to PHP's manual:

Returns TRUE for "1", "true", "on" and "yes". Returns FALSE otherwise.

If FILTER_NULL_ON_FAILURE is set, FALSE is returned only for "0", "false", "off", "no", and "", and NULL is returned for all non-boolean values.

Mladen Janjetovic
  • 13,844
  • 8
  • 72
  • 82
Eric Caron
  • 6,181
  • 1
  • 24
  • 26
  • 1
    does it also lowercase the value for the comparison? – Mobiletainment Nov 09 '13 at 19:23
  • 3
    @Mobiletainment, yes - it handles any casing you can imagine for $value (false, FALSE, FalSe, etc.) – Eric Caron Nov 12 '13 at 21:11
  • Borked testcase on my end. Used == instead of === for comparison. Will remove my earlier comment to not confuse people. – andig Dec 30 '15 at 10:01
  • I have never seen this before. Excellent solution. – Patrick Jun 03 '16 at 14:03
  • 7
    The answer caught me off guard because you have to add the flag ``FILTER_NULL_ON_FAILURE`` to the ``filter_var()`` function and NOT replace it with ``FILTER_VALIDATE_BOOLEAN`` as I thought. This will result in the following code which did the trick for me: ```$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)``` – Dragon54 Mar 23 '17 at 10:17
  • Also there is PHP's [`boolval()`](http://php.net/manual/pt_BR/function.boolval.php) (PHP 5 >= 5.5.0, PHP 7). Depending on one's needs, `boolval()` may be better. For what I need, [`filter-var()`](http://php.net/manual/pt_BR/function.filter-var.php) (PHP 5 >= 5.2.0, PHP 7) fits better. To choose between one or another, I suggest doing a test [like this](http://php.net/manual/en/function.filter-var.php#121263). – Antônio Medeiros Mar 08 '19 at 20:05
  • @AntonioViniciusMenezesMedei, the problem with your answer is `boolval('false')` returns **true** - which is the opposite of what's being requested in the question. boolval is great, but it isn't the right solve for this. – Eric Caron Jul 14 '20 at 19:30
16

The reason is that all strings evaluate to true when converting them to boolean, except "0" and "" (empty string).

The following function will do exactly what you want: it behaves exactly like PHP, but will also evaluates the string "false" as false:

function isBoolean($value) {
   if ($value && strtolower($value) !== "false") {
      return true;
   } else {
      return false;
   }
}

The documentation explains that: http://php.net/manual/en/language.types.boolean.php :

When converting to boolean, the following values are considered FALSE:

  • the boolean FALSE itself
  • the integer 0 (zero)
  • the float 0.0 (zero)
  • the empty string, and the string "0"
  • an array with zero elements
  • the special type NULL (including unset variables)
  • SimpleXML objects created from empty tags

Every other value is considered TRUE (including any resource).

Community
  • 1
  • 1
Arnaud Le Blanc
  • 98,321
  • 23
  • 206
  • 194
  • 2
    @Marco - if ($value && strtolower($value) !== "faux") { if you're working in French; if ($value && strtolower($value) !== "falsch") { in german; if ($value && strtolower($value) !== "onwaar") { in dutch... you can understand why PHP doesn't have this built in as standard – Mark Baker Jan 23 '11 at 17:58
  • 1
    "all **non-empty** strings evaluate to true when converting them to boolean, except "0"." – BoltClock Jan 23 '11 at 18:08
6

In PHP only "0" or the empty string coerce to false; every other non-empty string coerces to true. From the manual:

When converting to boolean, the following values are considered FALSE:

  • the empty string, and the string "0"

You need to write your own function to handle the strings "true" vs "false". Here, I assume everything else defaults to false:

function isBoolean($value) {
   if ($value === "true") {
      return true;
   } else {
      return false;
   }
}

On a side note that could easily be condensed to

function isBoolean($value) {
   return $value === "true";
}
Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
4

I recently needed a "loose" boolean conversion function to handle strings like the ones you're asking about (among other things). I found a few different approaches and came up with a big set of test data to run through them. Nothing quite fit my needs so I wrote my own:

function loosely_cast_to_boolean($value) {
    if(is_array($value) || $value instanceof Countable) {
        return (boolean) count($value);
    } else if(is_string($value) || is_object($value) && method_exists($value, '__toString')) {
        $value = (string) $value;
        // see http://www.php.net/manual/en/filter.filters.validate.php#108218
        // see https://bugs.php.net/bug.php?id=49510
        $filtered = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
        if(!is_null($filtered)) {
            return $filtered;
        } else {
            // "none" gets special treatment to be consistent with ini file behavior.
            // see documentation in php.ini for more information, in part it says: 
            // "An empty string can be denoted by simply not writing anything after 
            // the equal sign, or by using the None keyword".
            if(strtolower($value) === 'none') {
                $value = '';
            }
            return (boolean) $value;
        }
    } else {
        return (boolean) $value;
    }
}

Note that for objects which are both countable and string-castable, this will favor the count over the string value to determine truthiness. That is, if $object instanceof Countable this will return (boolean) count($object) regardless of the value of (string) $object.

You can see the behavior for the test data I used as well as the results for several other functions here. It's kind of hard to skim the results from that little iframe, so you can view the script output in a full page, instead (that URL is undocumented so this might not work forever). In case those links die some day, I put the code up on pastebin as well.

The line between what "ought to be true" and what oughtn't is pretty arbitrary; the data I used is categorized based on my needs and aesthetic preferences, yours may differ.

Matt Kantor
  • 1,704
  • 1
  • 19
  • 37
3

I'm using this construct to morph strings into booleans, since you want true for most other values:

$str = "true";
$bool = !in_array($str, array("false", "", "0", "no", "off"));
mario
  • 144,265
  • 20
  • 237
  • 291
1

Easiest Way to safely convert to a boolean;

    $flag = 'true';

    if( filter_var( $flag,FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ) !== null) {
      $flag = filter_var($flag,FILTER_VALIDATE_BOOLEAN);
    }

    gettype($flag); // Would Return 'Boolean'
    echo 'Val: '.$flag; // Would Output 'Val: 1'
Timothy Perez
  • 20,154
  • 8
  • 51
  • 39
1

Is there a function in PHP to parse "true" and "false" strings into boolean?

No - both are strings, and those both (as you say) evaluate to true. Only empty strings evaluate to false in PHP.

You would need to test for this manually. If at all possible, though, it would be better to work with "real" boolean values instead.

Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • 1
    Not all strings evaluate to `true` in PHP. – coreyward Jan 23 '11 at 17:43
  • 1
    Wasn't correcting, just clarifying. Saying "both are strings [and evaluate to `true`]" might give a newbie the wrong impression, especially one from another language with stricter typing rules where a string is a string and the contents don't matter when it's being converted to a boolean (like Ruby). – coreyward Jan 23 '11 at 17:47
  • 1
    _"Only empty strings evaluate to false in PHP."_ But what about the non-empty string `"0"`? Doesn't this also evaluate to `false`? – Sepster Aug 27 '15 at 14:00
0

If your API only accepts the strings "true" or "false", with everything else becoming null, then try:

$boolean = ['true' => true, 'false' => false][$inputString] ?? null;

This assumes that $input is not an object. Null coalesce (??) was introduced in PHP 7.0.

Matt Janssen
  • 1,505
  • 13
  • 14