简体   繁体   中英

PHP Comparing 0 does not work

I'm trying to set a checkbox as checked in php based on an hour fields from a comma separated value string. It works well for 1-23 but for some reason hour 0 always displays as checked:

<?php
myhours = explode(",", substr($arruser['arhours'],0,strlen($arruser['arhours']) - 1));
$checked = "";
for($hour = 0; $hour <= 23; $hour++) {
    if(count($myhours) > 0) {
        for($h = 0; $h <= count($myhours); $h++) {
            if((int)$hour == (int)$myhours[$h]) {
                $checked = " checked ";
                break;
            }
        }
    } else {
        $checked = "";  
    }
    if(strlen($hour) == 1) {
        echo "<td><input type=checkbox " . $checked . " value=" . $hour . " onchange=\"updatehour(" . $_REQUEST['user'] . ",this.checked, '" . $hour . "')\">0$hour:00</td>";   
    } else {
        echo "<td><input type=checkbox " . $checked . " value=" . $hour . " onchange=\"updatehour(" . $_REQUEST['user'] . ",this.checked, '" . $hour . "')\">$hour:00</td>";
    }
    $checked = "";
}
?>

The problem is straightforward; look at the outer loop:

for ($hour = 0; $hour <= 23; $hour++) {

Consider only the first iteration, so $hour is int(0) . Further in the code:

if(count($myhours) > 0) {
    for($h = 0; $h <= count($myhours); $h++) {

Pay close attention to the loop condition:

$h <= count($myhours)

Consider the last iteration of that loop, so $h equals the size of your array.

if ((int)$hour == (int)$myhours[$h]) {

At this point $myhours[$h] is undefined because the array index is out of bounds (and a notice would have been emitted) and so (int)$myhours[$h] becomes (int)null which is int(0) . The comparison is therefore always true when $hour has the value of int(0) .

The solution is to change the loop condition to:

$h < count($myhours)

Not exactly and answer, but your code could be reduced to this:

$myhours = array(0, 10, 13, 20);
for($hour = 0; $hour <= 23; $hour++) {
    echo '<td><input type="checkbox"' . ( in_array($hour, $myhours) ? ' checked' : '' ) . ' value="' . $hour . '" onchange="updatehour(' . $_REQUEST['user'] . ', this.checked, ' . $hour . ')">' . str_pad($hour, 2, '0', STR_PAD_LEFT) . ':00</td>';   
}

No need for a second loop and more variables here. Also be aware to not output values from $_REQUEST directly without any check.

Demo

Try before buy

Problem solved. It was actually the count($myhours) that was causing the problem. Basically even with an empty string it still returns an array with 1 element. Changed to check if count($myhours) > 1 and everything is working as expected:

<?php
$myhours = explode(",", substr($arruser['arhours'],0,strlen($arruser['arhours']) - 1));
$checked = "";
for($hour = 0; $hour <= 23; $hour++) {
    if(count($myhours) > 1) {
        for($h = 0; $h <= count($myhours); $h++) {
            if((int)$hour == (int)$myhours[$h]) {
                $checked = " checked ";
                break;
            }
        }
    } else {
        $checked = "";  
    }
    if(strlen($hour) == 1) {
        echo "<td><input type=checkbox " . $checked . " value=" . $hour . " onchange=\"updatehour(" . $_REQUEST['user'] . ",this.checked, '" . $hour . "')\">0$hour:00</td>";   
    } else {
        echo "<td><input type=checkbox " . $checked . " value=" . $hour . " onchange=\"updatehour(" . $_REQUEST['user'] . ",this.checked, '" . $hour . "')\">$hour:00</td>";
    }
    $checked = "";
}
?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM