php / php-src

The PHP Interpreter
https://www.php.net
Other
38.23k stars 7.75k forks source link

elseif($data->get('elseif') is '0' but behaves like 0 #16125

Closed remco-pc closed 1 month ago

remco-pc commented 1 month ago

Description

The following code:

{{$counter = 1}}
{{$elseif = '0'}}
{{d($elseif)}}
{{while(true)}}
    {{$counter}}
    {{$counter++}}
    {{if($counter > 10)}}
        {{break()}}
    {{elseif($elseif)}}
        {{$counter}} under 11 #error
    {{elseif((string) $elseif)}}
        {{$counter}} under 11 #test
    {{elseif($elseif === '0')}}
        {{$counter}} under 11 #ok
    {{else}}
        {{$counter}} up 2
    {{/if}}
{{/while}}

Resulted in this output:

string(1) "0"
1
2 under 11 #ok
2
3 under 11 #ok
3
4 under 11 #ok
4
5 under 11 #ok
5
6 under 11 #ok
6
7 under 11 #ok
7
8 under 11 #ok
8
9 under 11 #ok
9
10 under 11 #ok
10

But I expected this output instead:

string(1) "0"
1
2 under 11 #error
2
3 under 11 #error
3
4 under 11 #error
4
5 under 11 #error
5
6 under 11 #error
6
7 under 11 #error
7
8 under 11 #error
8
9 under 11 #error
9
10 under 11 #error
10

under the hood the "rax" template compiles down to php code where d is the debug function which outputs its a string '0' and it behaves like 0 for the first 2 elseifs the third, which is checking === under the hood is correct, but the other two should react first...


$data->set('counter', 1);
$data->set('elseif', '0');
$this->d($data->get('elseif'));
while(
    true
){
    $data->set('counter', $this->value_plus_plus($data->get('counter')));
if(
    $this->value_greater($data->get('counter'), 10)
){
    break;
}
elseif(
   $data->get('elseif')
){
   echo $data->get('counter');
   echo ' under 11 #error';
}
elseif(
   ( string ) 
   $data->get('elseif')
){
   echo $data->get('counter');
   echo ' under 11 #test';
}
elseif(
   $this->value_identical($data->get('elseif'), '0')
){
   echo $data->get('counter');
   echo ' under 11 #ok';
} else {
   echo $data->get('counter');
   echo 'up 2';
}
}

PHP Version

8.3.11

Operating System

Debian 12

nielsdos commented 1 month ago

So if I understand it correctly, this is basically the same to your original code: https://3v4l.org/nqaUa Note that '0' is a falsy value, so the "error" branch won't be taken, which is expected. Therefore you end up with "ok". Unless I misunderstood, there's no bug here.

remco-pc commented 1 month ago

@nielsdos

<?php
/**
 * same behaviour as in the template engine
 * $list = [], list is empty
 * $list = (object) [], list is not empty
 * $list = false, list is empty
 * $list = null, list is empty
 * $list = 0, list is empty
 * $list = 1, list is not empty
 * $list = '', list is empty
 * $list = '0', List is not empty', list is empty in template engine
 */
$list = '0';
var_dump($list);
$counter = null;
if($counter === 0){

}
elseif($list){
    echo 'List is not empty';
}
else{
    echo 'List is empty';
}
remco-pc commented 1 month ago

@nielsdos i see now, list is empty on 0, i swear it was not empty !, sorry for any inconvinient, the co-pilot did this wrong too and made me doubt...