Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
но после понимания что есть разница между == и ===, программист должен проклятсь нестрогую типизацию и начать думать как сравнивать правильно в том или ином случае.
' 7' == 7, а '7 ' != 7. Или что строка '0' приводится к false, а строка 'false' — нет.// Использование функции "strcmp" strcmp($aaa, $bbb) == 0;
php > var_dump(strcmp("hello", array(123)));
Warning: strcmp() expects parameter 2 to be string, array given in eval()''d code on line 1
NULL
php > var_dump(NULL == 0);
truephp > var_dump(json_decode('{"a": 123, "b": "123"}'));
object(stdClass)#1 (2) {
["a"]=> int(123)
["b"]=> string(3) "123"
}
php > var_dump(json_decode('{"number": 12345678901234567890}', false, 512, JSON_BIGINT_AS_STRING));
class stdClass#1 (1) {
public $number =>
string(20) "12345678901234567890"
}
php > var_dump(json_decode('{«number»: 12345678901234567890}'));
class stdClass#1 (1) {
public $number =>
double(1.2345678901235E+19)
}
php > var_dump(json_decode('{"n": 12345678901234567890}')->n === 12345678901234567890);
bool(true)
php > var_dump(json_decode('{"n": 12345678901234567890}', false, 512, JSON_BIGINT_AS_STRING)->n === 12345678901234567890);
bool(false)
php> var_dump(7 == '7_nabor_bukav');
bool(true)
var_dump('7' == '7_nabor_bukav'); // false
Из-за того, что в PHP при сравнении строк оператор "==" пытается сначала преобразовать их в числа [1][2] (даже, если оба операнда — строки).
var_dump('123' == ' 123'); // true
var_dump('123' == '123 '); // false
Это я вам к тому, что тема не раскрыта полно.
The conversion to a number is necessary because programmers don't differentiate
between strings and numbers in PHP. Consider the following code:
if ($_GET[«a»] == $_GET[«b»]) echo «a is same as b!»;
The result will be the same if the query string is ?a=1&b=1 or ?a=1&b=1.0 or?
a=01&b=1 because PHP is loosely typed.
Internally $_GET[«a»] and $_GET[«b»] are both strings, but we can't do a string
comparison. If you want a string comparison, use strcmp.
PHP has two sets of comparison operators as well. == and ===
They aren't numeric and string, they are loose and strict. In the majority of
cases when dealing with HTTP requests and database results, which is what PHP
deals with most, the loose comparison makes life easiest on the developer.
If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value.
В случае, если вы сравниваете число со строкой или две строки, содержащие числа, каждая строка будет преобразована в число, и сравниваться они будут как числа. Эти правила также распространяются на оператор switch. Преобразование типов не происходит при использовании === или !== так как в этом случае кроме самих значений сравниваются еще и типы.
'7 ' содержит числа, но со второй строкой будет сравниваться как строка, ('7 ' == '7') === false, а, емнип, строка является числовой (is_numeric('7 ') === false, хотя ((integer)'7 ') === 7).'7 ' для php не число, а ' 7' — число (пробелы с разных строн). Вам очевидны правила, по которым php принимает такое решение?Проверяет, является ли переменная числом или строкой, содержащей число
'7 ' содержит число, но как число не интерпретируется! И не всегда программист может знать, что придет на входе и рассчитывает на неявное приведение типов при нестрогом сравнении, но не настолько же неявном, что даже мануал ситуацию описывает неоднозначно.if (gettype($_REQUEST['password']) == gettype($_REQUEST['password_confirm'])
&& $_REQUEST['password'] == $_REQUEST['password_confirm'])) {
// ...
}
$a == $b Equal TRUE if $a is equal to $b after type juggling.
$a === $b Identical TRUE if $a is equal to $b, and they are of the same type.
if ($_REQUEST['password'] === $_REQUEST['password_confirm'])) {
// ...
}
array(2) {
["pass"]=> string(1) "7" // просто 7
["pass_confirm"]=> string(2) " 7" // пробел 7
}
bool(false)
string(32) "8f14e45fceea167a5a36dedd4bea2543"
string(32) "6b958f957985dc14ee63064715e541f3"
== и ===. Но == в некоторых случаях (is_numeric истинно для обоих операндов как минимум) производит ещё более нестрогую проверку, чем от него ожидаешь. Проблема PHP во многом в том, что в нём очень много таких нюансов, которые быстро забываются.false == func() классика, на нем ошибаешься только один раз :) Просто ради интереса, можете привести пример, когда программист не знает что пихнет юзер/источник.
Видимо мне повезло и еще в начале пути я узнал в чем отличия между == и ===, и чтобы не было недопонимания у php, использую или строки, или числа в явном виде
дык, PHP кастует строку в число, используя ее до первого нечислового символа:
«123qwe» == 123
&&/and и ||/or взаимозаменяемыми. На чем и горят:2 && 0 ? 'a' : 'b' // b
2 and 0 ? 'a' : 'b' // 1'b' и true соответственноif (expr) {
true
} else {
false
}
$a = true and false;
var_dump($a); //true
$a = false or true;
var_dump($a); //false
$var = 0 or trigger_error('Notice ...'); встречаются.все всё ВСЁ сравнивается как строки при нестрогом сравнении
(string)$var1 == (string)$var2 может сравниваться как числа."9" > 11 и "9" > "11"? Первый случай я еще могу понять — перед сравнением нужно привести к одному типу. Второй нет.нужно привести их к числам.
В нестрого типизованном языке другие правила.
Но перед тем попробуйте смоделировать ситуацию, когда числовые строки сравниваются как строки, а не как числа.
var_dump(is_numeric("\n\t\r\v\f 0000123")); // bool(true)
((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/)
|| (oflow1 == -1 && dval1 < -9007199254740991.))
$id1 = '9223372036854775888';
$id2 = '9223372036854775899';
var_dump(is_numeric($id1)); // bool(true)
var_dump(is_numeric($id2)); // bool(true)
var_dump($id1 == $id2); // bool(false)
Используете ли вы оператор нестрогого сравнения ("==") в PHP?