1

我对比较“错误”感到困惑。我编码这个比较的方式,我想确保如果用户输入0 或 1(或没有值)以外的任何值,结果应该是 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');

但是,它会中断,test('ready');因为它输出Variable value: ready | Session value: readyRATHER THAN Variable value: 0 | Session value: 0case o:即使它正在将数字与字符串进行比较,它也应该继续正常工作(并继续前进)。

顺便说一句:即使我替换switch为,结果也是一样的if( $status ===

=== 编辑:2012 年 12 月 19 日 ===
感谢@bryan-b@jatochnietdan的评论和回答:-Because a string (when compaired with numbers [if( 0 == 'string')] ) is compared as 0

这帮助我找出了问题并了解到,与其他语言不同,它不会在比较中自动返回 false,因为它们具有不同的数据类型;php 比较字符串变量,就好像它们的值与数字比较时为 0。这是需要注意的。

这是更正的(工作)代码:

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');

谢谢@bryan-b@jatochnietdan!!!

PS。我希望我可以投票 2 个答案。

4

4 回答 4

5

如果您真正想要的只是 $_SESSION['status'] 的值在输入 1 以外的任何值时为 0,那么这就足够了:

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

通过您的测试,这些值将如下所示:

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

编辑:修正了一个小错误,它默认为 1,但我相信你希望它默认为 0。

至于您的代码,它出现“就绪”的原因是因为您将 $_SESSION['status'] 设置为 $status 以防 0 并且 $status 在该实例中包含“就绪”。你可以通过简单地做 $_SESSION['status'] = 0 来解决这个问题。

于 2012-12-19T23:07:38.003 回答
3

我认为这里的问题是 php 将字符串“ready”转换为整数,因此大小写比较有效。从 php 文档(http://php.net/manual/en/function.intval.php):

字符串很可能返回 0,尽管这取决于字符串最左边的字符。整数转换的通用规则适用。

我在(工作)函数中添加了一个回显,显示当将字符串转换为 int 以进行开关比较时 php 正在做什么。您需要检查传入状态的确切值和类型。

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');
于 2012-12-19T23:05:04.467 回答
1

发生这种情况是因为 php 中的 switch 使用了一种叫做:松散比较的东西。

这意味着字符串的"value"计算结果为0,因此它永远不会像您想象的那样达到默认值。

于 2012-12-19T23:11:28.203 回答
0

PHP 是松散类型的,字符串输入可以作为整数进行评估以进行比较(事实上,我认为无论如何您的代码都依赖于此)。

包含非数字字符的字符串将评估为整数 0 - 因此您在 switch 语句中的案例将像 0 到 '0' 和 1 到 '1' 一样容易地匹配 0 到 'ready'。

所以 - 你可以这样做:

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

或者使用ctype函数来检测字符串中的数值。

于 2012-12-20T00:05:41.740 回答