0

I have been testing a simple long poll on my website, and for some reason a chunk of my server-side code is being executed despite the variable that triggers it ($init) being false.

I have a small hunch that the problem lies within the client-side code, but I can't seem to figure out what it is.

Code


Client Side - JavaScript:

window._Poll: {
    listen: function(init){
        $.ajax({
            url: "/poll.php",
            method: "post",
            data: { init: init },
            success: function(res){
                console.log(res);
                /* set the init variable to false in the next run */
                _Poll.listen(false);
            }
        });
    }, init: function(){
        /* set the init variable to true in the first run */
        this.listen(true);
    }
}
/* on page load */
_Poll.init();

Server Side - PHP:

set_time_limit(0);
session_write_close();

if(isset($_POST["init"]) && ($_POST["init"] == true || $_POST["init"] == false)){
    /* the first time this script is called, this variable is true - but for the
    *  second time and onwards it is false (like it should be) */
    $init = $_POST["init"];
    echo $init;

    /* therefore this block should only be firing once as init is only true once */
    if($init){
        if(/* some more database checking */){
            die("true");
        }
    } else {
        die("false");
    }
}

The console output for this the second time and onwards is

false true

When in reality it should be

false false


I have been really stuck on this, and from what I could find, nothing seems to be able to help me. So any help is appreciated,
Cheers.

Teemu
  • 22,918
  • 7
  • 53
  • 106
GROVER.
  • 4,071
  • 2
  • 19
  • 66
  • 3
    `$_POST["init"] == true || $_POST["init"] == false` will always be true. It's either ture or its false, and you say "*if its true of if its false, then..*". Seems moot- – Qirel May 08 '19 at 10:29
  • @Qirel I'm aware. It's to check if that variable is a boolean - since `is_bool` doesn't work on strings (and that's what will be passed in the post method). It's kind of ghetto, but I tested it and it works. – GROVER. May 08 '19 at 10:30
  • 1
    But you're checking against booleans, so it's moot. To your actual question, do a `var_dump($_POST['init'])` and see what you get. If you get a string of "false", then `if ("false") {` is still true (because a string is a truthy value). – Qirel May 08 '19 at 10:31
  • 1
    You probably mean to write: `$_POST["init"] == "true" || $_POST["init"] == "false"`? Depending on the true value of `init` of course. – KIKO Software May 08 '19 at 10:31
  • @KIKOSoftware now I may be mistaken, but considering I used `==` instead of `===`, it doesn't matter whether or not they're strings. – GROVER. May 08 '19 at 10:33
  • 1
    `"false" == true` because a string is a truthy value. A string of "false" is not the same as the boolean `false`. – Qirel May 08 '19 at 10:34
  • You are passing strings and not booleans. Echoing out a boolean false won't print anything - and yet it's printing `false`. Just change the check to be `if($init == 'true'){` – Nigel Ren May 08 '19 at 10:34
  • As far as I am aware, `$_POST` will always contain strings. They could be numeric string, you can treat as numbers, but strings nontheless. – KIKO Software May 08 '19 at 10:34
  • I think you should check the link attached, it should answer your question. The issue seems to be that only "FALSE" is considered to be false, but "false" will not be. Thus, you should check if your String is "false" https://stackoverflow.com/questions/2382490/how-does-true-false-work-in-php – Illedhar May 08 '19 at 10:34
  • @KIKOSoftware Correct! POST is *always* a string, but an actual boolean can be 1/0 (please correct me if I'm wrong). – Qirel May 08 '19 at 10:35
  • @Qirel No, you're right. True booleans will probably come out as `"1"` or `"0"`. Simply check what you actually get, and you will know. Believing is one thing, knowing is better. – KIKO Software May 08 '19 at 10:36
  • @KIKOSoftware so essentially, I should be checking init like this? `$init == "true"` – GROVER. May 08 '19 at 10:38
  • Best just echo `$_POST["init"]` in PHP, so you know. I think it will probably be a `"1"` string in PHP, when it is `true` in javascript and a `"0"` or `""` string when it is `false` in javascript. – KIKO Software May 08 '19 at 10:40
  • Yes...you need to check for the string value "true" (or whatever value is actually being sent by the client) rather than the boolean value, because the POST array contains strings, not bools – ADyson May 08 '19 at 10:43

1 Answers1

2

All values received from POST are strings. So if you're passing the string of "false", comparing that loosely to true will be a true result - "false" == true is true, as a string is truthy.

Checking for $_POST["init"] == true || $_POST["init"] == false doesn't make much sense, so you can instead check if the value is either equal to the strings "true" or "false"

if(isset($_POST["init"]) && (in_array(strtolower($_POST["init"])), ["true", "false"])){
    /* the first time this script is called, this variable is true - but for the
    *  second time and onwards it is false (like it should be) */
    $init = $_POST["init"];
    echo $init;

    /* therefore this block should only be firing once as init is only true once */
    if (strtolower($init) === "true"){
        if(/* some more database checking */){
            die("true");
        }
    } else { // Alternatively check if the string is "false", but then you can consider having a default return value other than "false"?
        die("false");
    }
}
``
Qirel
  • 25,449
  • 7
  • 45
  • 62