2015-12-02 2 views
1

Если установить $var к string в PHP, что переменная будет вычисляться true в любых условиях:PHP: Понимание строки типа жонглирования

$var = "foo"; 
if ($var) { 
    echo 'I will be printed'; 
} else { 
    echo 'I will not be printed'; 
} 

Я понимаю, что мое состояние выше автоматически делает Манипуляции так, что $var является преобразованный в bool.

Теперь, если я бросаю $var к integer, я получаю 0:

var_dump((int)$var); // int(0) 

0 это значение falsy, которая становится false при преобразовании в bool:

$zero = 0; 
var_dump((bool)$zero); // bool(false) 

Учитывая выше, почему мое состояние не печатает «Я не буду печататься»?

+2

Это [false] (http://php.net/manual/en/language.types.boolean.php). Пустая строка, строка «0» и NULL. Если строка является числовой, она будет содержать это значение при передаче в INT, иначе она будет выбрана равной 0 или FALSE. –

+0

Проверьте эту ссылку для сравнения типов: http://www.php.net/manual/en/types.comparisons.php –

+0

Спасибо за ваши ребята. Я думаю, что Нить Темный Абсолют [ответ] (http://stackoverflow.com/a/34044476/1709033) объясняет это. Нет промежуточного шага преобразования в 'int', когда условие выполняет жонглирование типа: оно идет прямо из' string' в 'bool'. – henrywright

ответ

5

Тип жонглирования не является без потерь. Он поставляется с потенциальной потерей данных.

Например ...

var_dump(strval(intval("foo"))); // string(1) "0" 

Но если вы напишете ...

if("foo" == "0") // non-strict comparison intended 

Вы бы, конечно, не ожидал, что бежать! И действительно, нет.

Так как изменения типа происходят с потерей данных, вы не можете ожидать, что преобразования будут эквивалентными. Другими словами, boolval(intval($var)) и boolval($var) не обязательно должны быть одинаковыми.

Если вы хотите быть строгим в своих сравнениях, использовать что-то вроде этого:

if(is_string($var) && $var !== "") // is not the empty string 

(Возможно !== избыточно и != работает отлично, но, возможно, все это условие является излишним)

+0

, поэтому механизм juggling типа условия преобразует 'string' непосредственно в' bool' без промежуточного шага преобразования в 'int'? Это имеет смысл и объясняет, почему выражение условия оценивает значение 'true' – henrywright

0

Вы будете не получить else эхо сделано, как строка, которая не является пустым имеет значение верно, когда используется в случае, то есть:

$foo = "Hello"; 
if ($foo) 
    print "True"; //This will print as a string is true if not empty 
else 
    print "False"; //Doesn't print as string is not empty 

Попробуйте это:

$foo = "Hello"; 
if ((int)$foo) 
    print "True"; 
else 
    print "False"; //Will print as the string evaluates to 0 (false) as it is not an integer 
+0

@Uchiha, но я попытался показать, что происходит, когда строка является типом, отличным от int, где она имеет строковое значение (az AZ) –

1

Вот простой тест истины:

$s = array(// bool (int)cast 
    '',  // FALSE int=0 
    'Test', // TRUE int=0 
    '0.0', // TRUE int=0 
    '124', // TRUE int=124 
    '000', // TRUE int=0 
    '0', // FALSE int=0 
    NULL // FALSE int=0 
); 


foreach($s as $var) 
    echo $var . ' // ' 
     . ($var ? 'TRUE' : 'FALSE') . ' ' 
     . 'int=' . (int)$var . PHP_EOL; 

В случае строки литейным BOOL, FALSE пустая строка, NULL, а значение «0». Все остальное - TRUE. См. Руководство по телефону false.

В вашем случае, $var строка «Foo», которая не преобразуется в FALSE, поскольку он не является ни NULL, «0» или «», поэтому вы не получите "Я не печатается.

Если вы передали его INT, все равно 0, за исключением чистого численного значения.

+0

Могу ли я спросить, как это отвечает на вопрос? –

+0

@SamSwift 웃: Quote henrywright 'почему мое состояние не печатает «Я не буду печатать»? - потому что только строки '', '0' и NULL преобразуются в 'FALSE'. Измените строку, и вы получите «Я не буду напечатан» –

+0

Спасибо за разъяснение :) –

Смежные вопросы