1

I am way confused with a comparison "error". The way I coded this comparison, I want to make sure that if the user inputs any value other than 0 or 1 (Or no value), the result should be 0:

session_start();
function test( $status = 0 ) {
        if( !isset($_SESSION['status']) ) { $_SESSION['status'] = 0; }
        else {
            switch( $status ) {
                case 0: $_SESSION['status'] = $status;
                break;

                case 1: $_SESSION['status'] = $status;
                break;

                default:
                $_SESSION['status'] = 0; 
                $status = 0;
            }
        }
        echo 'Variable value: ' . $status;
        echo ' | Session value: ' . $_SESSION['status'] . "<br/>";
}
test();
test(0);
test(1);
test(999);
test('ready');

HOWEVER, it breaks at test('ready'); BECAUSE it outputs Variable value: ready | Session value: ready RATHER THAN Variable value: 0 | Session value: 0. It should continue to work well (and go for case o:) even if it is comparing numbers against a string.

BTW: The result is the same even if I replace switch for if( $status ===

=== EDIT: 12/19/2012 ===
Thanks to @bryan-b and @jatochnietdan comments and answers: -Because a string (when compaired with numbers [if( 0 == 'string')] ) is compared as 0

That helped me figure out the problem and learned that, unlike in other languages, rather than automatically returning false in a comparison, since they are of different data-types; php compares string variables as if their value is 0 when compared against numbers.THAT'S SOMETHING TO WATCH OUT FOR.

This is the corrected (working) code:

session_start();
function test( $status = 0 ) {
        if( !isset($_SESSION['status']) ) { $_SESSION['status'] = 0; }
        else {
            switch( $status ) {
                case 1: $_SESSION['status'] = $status;
                break;

                default:
                $_SESSION['status'] = 0; 
                $status = 0;
            }
        }
        echo 'Variable value: ' . $status;
        echo ' | Session value: ' . $_SESSION['status'] . "<br/>";
}
test();
test(0);
test(1);
test(999);
test('ready');

Thank you @bryan-b and @jatochnietdan!!!

PS. I wish I could vote 2 answers.

7
  • what do you mean "it breaks"? Commented Dec 19, 2012 at 23:00
  • 1
    Do you want to throw exception if string is used ?? because string would be evaluated has 0 which is your default .. nothing is broken Commented Dec 19, 2012 at 23:01
  • FYI: Even if a string is treated as 0 (Or FALSE), my code should (in theory) work and go for case o: rather than outputting the string. Commented Dec 19, 2012 at 23:18
  • Your code does work and go to case 0. The problem is you're setting the $_SESSION variable to $status which is not set to 0. If you want to fix that, simply change to case 0: $_SESSION['status'] = 0; and not = $status. Commented Dec 19, 2012 at 23:19
  • Your code is working just as it should, which is truly the annoying thing with code sometimes. Commented Dec 19, 2012 at 23:21

4 Answers 4

5

If all you truly want is for the value of $_SESSION['status'] to be 0 if anything other than 1 is entered, then this should suffice:

function test( $status = 0 ) {
    $_SESSION['status'] = ($status == 1 ? 1 : 0);
}

With your tests, the values will be as follows:

Session value: 0
Session value: 0
Session value: 1
Session value: 0
Session value: 0

Edit: Fixed a slight mistake, it was defaulting to 1 but I believe you want it to default to 0.

As for your code, the reason it's coming up as "ready" is because you're setting $_SESSION['status'] to $status in case 0 and $status contains "ready" in that instance. You could fix that by simply doing $_SESSION['status'] = 0.

Sign up to request clarification or add additional context in comments.

4 Comments

I need the comparison to work as well. -It is part of a much larger app
shouldn't it be $status === 0 ?
This is a great answer (also see @Ben's comment)....if you're unsure what that ternary operator is, it is a simple if else statement. If (session is 0) then set it to 0, else: set it to one. sounds like exactly what you wanted. then add in the rest of your code below it...
@jatochnietdan You do have a VERY good point here. However, I would've change the code to $_SESSION['status'] = ($status == 1 ? 1 : 0); but my problem is about comparing different variable types AND I DO need the comparison function, since it is part of some other things (It's hard for me to explain). But yes, I do agree that $_SESSION['status'] = ($status == 1 ? 1 : 0); it's simpler and better.
3

I think the problem here is that php is casting the string "ready" to an integer, so the case comparison works. From the php docs (http://php.net/manual/en/function.intval.php):

Strings will most likely return 0 although this depends on the leftmost characters of the string. The common rules of integer casting apply.

I've added an echo into the (working) function showing what php is doing when casting the string to an int for the switch comparisons. You need to be checking the exact value and type of the passed in status.

function test($status = 0){
    if(!isset($_SESSION['status']) || $status !== 1){ 
        $_SESSION['status'] = 0; 
    }
    else {
        $_SESSION['status'] = 1;
    }

    echo 'Variable value: ' . $status;
    echo ' | Variable value (int): ' . (int)$status;
    echo ' | Session value: ' . $_SESSION['status'] . "<br/>";
}
test();
test(0);
test(1);
test(999);
test('ready');

2 Comments

Even if a string is treated as 0 (Or FALSE), my code should (in theory) work and go for case o: `rather than outputting the string.
Right, but in your example, case 0 sets the $_SESSION['status'] key to the passed in $status variable, not 0. So php is type casting for the switch case comparison, and then using the value directly for setting the $_SESSION key, if that makes sense. In other words, you could change "case 0: $_SESSION['status'] = $status;" to "case 0: $_SESSION['status'] = 0;" and it ought to work as you anticipated.
1

This happens because switch in php uses something called: loose comparison.

That means that the string "value" evaluates to 0 and thus it never reaches default as you might think.

2 Comments

The result is the same even if I replace switch for if( $status ===
Are you saying that "case 0:" and "if($status === 0)" both return true if status has the value 'ready'?
0

PHP is loosely typed, and string input can be evaluated as integers for comparisons (in fact, I think you're relying a bit on this for your code anyway).

Strings containing non-numeric characters will evaluate as integer 0 - so your cases in your switch statement will match 0 to 'ready' as easily as 0 to '0', and 1 to '1'.

So - you could just do:

$_SESSION['status'] = 0;
if ($status == 1) {
  $_SESSION['status'] = 1;
}

Or make use of ctype functions to detect numeric values in strings.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.