boolean variables posted through AJAX being treated as strings in server side
Asked Answered
D

4

45

Following is a part of an AJAX functionality to add classes and packs to session cart:-

The jquery part

function addClassToCart(itemId)
{
   addItemToCart(itemId,true);
}

function addPackToCart(itemId)
{
   addItemToCart(itemId,false);
}

function addItemToCart(itemId,isClass)
{   
     $.post(url+"/ajax/add_cart", { operation: 'add_cart','isClass':isClass, 'itemId': itemId},
        function(data)
        {
               if(data.success)
               {
                      alert("item added to cart");
               }
        }, "json");

}

The AJAX request processing php part -

//Checking operation and other posted parameters
if($_POST['isClass'])
{
  //Code to add class to session cart

}
else
{
  //Code to add pack to session cart
}

The strange thing

No matter whether I pass true/false (by calling addClassToCart() and addPackToCart()), always the code to add class to session cart executes.
If I put echo statements there like this:-

    if($_POST['isClass'])
    {
      echo "see if condition ".$_POST['isClass'];
    }
    else
    {
      echo "see else condition ".$_POST['isClass'];
    }

This is the output:-

addClassToCart() see if condition true
addPackToCart() see if condition false

Putting conditions like this in the jquery code however works fine:-

function addItemToCart(itemId,isClass)
 {  
     if(isClass)
        alert("is class");
     else
        alert("is pack");
 }

Finally, if I alter the server side code to this:-

if($_POST['isClass'] === true)
        {
          echo "see if condition ".$_POST['isClass'];
        }
        else
        {
          echo "see else condition ".$_POST['isClass'];
        }

These are the outputs -

addClassToCart() see else condition true
addPackToCart() see else condition false

So, why is the boolean variable treated as a string here? Am I doing something wrong in posting parameters?

Thanks, Sandeepan

Dungaree answered 6/9, 2010 at 21:44 Comment(2)
That is definitely not unexpected. Everything passed via GET or POST to PHP are strings.Accrue
yes I see now... edited my question titleDungaree
J
57

You aren't doing anything wrong per se, it's just that when it gets posted, it looks like this:

operation=add_cart&isClass=true&itemId=1234

PHP can't tell what the data type is because it isn't passed, it's always just a string of POST data, so compare it to "true" to do your checks, like this:

if($_POST['isClass'] === "true")
{
  //Code to add class to session cart
}
else
{
  //Code to add pack to session cart
}
Jamnis answered 6/9, 2010 at 21:47 Comment(7)
So is there no other way around? I prefer doing boolean checks as much as possible.Dungaree
@sandeepan - nope, not sure what else to say other than...this is how http gets and posts work, it's perfectly normal.Jamnis
Why not instead use '==' and let it do type conversion for you?Merely
@Merely - Because it's a string , "false" is still true because it's a non-zero length string...be explicit and you won't get surprises. The same rules apply to JavaScript for example, some people never use == and only use === for good reason.Jamnis
I guess I had a misconception of type conversion. Thanks Nick.Merely
you can type cast it to a boolean like so $foo = (bool) $_POST['foo'];Scrutinize
@Scrutinize You would need to explicitly test for 'true' and 'false' and reset those values to booleans. The string 'false' cast as a boolean will be true. Check out us2.php.net/manual/en/language.types.boolean.php to review how PHP converts such values.Chophouse
G
83

Also you can use filter_var function with filter FILTER_VALIDATE_BOOLEAN. According to php documentation it

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.

So receiving of POST parameter will look like:

$isClass = filter_var($_POST['isClass'], FILTER_VALIDATE_BOOLEAN);
Goldengoldenberg answered 9/12, 2013 at 4:52 Comment(8)
+1 for filter_var, one of the often overlooked parts of the PHP.Triage
Beautiful! Validating a boolean like it were a string is imho ugly and fubar.Publicspirited
Although I voted up the top three answers this was the one that was so clean and elegant, it made it into my code. Well done.Endlong
The best solution for retrieving the data in Ajax or Api.Sardinian
Please get rid of the space between filter_var and its parentheses, it makes the code only slightly harder to read but unimaginably disrupting to my internal peace and the system won't let me make such a minor edit. 😬Lefthander
@HashimAziz done! Hope it brought internal peace to you :)Goldengoldenberg
@Goldengoldenberg If only, but close enough. Haha thanksLefthander
In case if $_POST['isClass'] hasn't been passed at all (ie $_POST['isClass'] is NULL), filter_var($_POST['isClass'], FILTER_VALIDATE_BOOLEAN); will return false as well.Fractionize
J
57

You aren't doing anything wrong per se, it's just that when it gets posted, it looks like this:

operation=add_cart&isClass=true&itemId=1234

PHP can't tell what the data type is because it isn't passed, it's always just a string of POST data, so compare it to "true" to do your checks, like this:

if($_POST['isClass'] === "true")
{
  //Code to add class to session cart
}
else
{
  //Code to add pack to session cart
}
Jamnis answered 6/9, 2010 at 21:47 Comment(7)
So is there no other way around? I prefer doing boolean checks as much as possible.Dungaree
@sandeepan - nope, not sure what else to say other than...this is how http gets and posts work, it's perfectly normal.Jamnis
Why not instead use '==' and let it do type conversion for you?Merely
@Merely - Because it's a string , "false" is still true because it's a non-zero length string...be explicit and you won't get surprises. The same rules apply to JavaScript for example, some people never use == and only use === for good reason.Jamnis
I guess I had a misconception of type conversion. Thanks Nick.Merely
you can type cast it to a boolean like so $foo = (bool) $_POST['foo'];Scrutinize
@Scrutinize You would need to explicitly test for 'true' and 'false' and reset those values to booleans. The string 'false' cast as a boolean will be true. Check out us2.php.net/manual/en/language.types.boolean.php to review how PHP converts such values.Chophouse
G
20

This is a bit of an old question, but I'm surprised nobody has posted this here as solution.

Just use 1 and 0 instead of true and false when you're constructing your ajax requests. When you do a == comparison, they'll be interpreted as true/false.

JS:

$.ajax({
  url: '....',
  data: {
    foo: 1,
    bar: 0
  }
});

PHP:

<?php
  if ($_GET['foo']) {
     //...
  } else {
     //...
  }

  echo $_GET['bar'] ? 'bar is true' : 'bar is false';
?>
Gambell answered 12/3, 2013 at 20:40 Comment(0)
S
1
  1. Send the data from your javascript as stringified JSON.
  2. Make a PHP function to convert the strings 'true' and 'false' to boolean value.

Personally I like #2, which goes with Nick Craver's answer.

Selfreliance answered 6/9, 2010 at 22:36 Comment(1)
number 1 works far better when the object you want to save is multi-leveled.. no ugly recursive php functions required just json_decodeGumbo

© 2022 - 2024 — McMap. All rights reserved.