Столкнулся с особенностью приведения типов в PHP. Это вроде и известно, но сегодня я попался на этом.
Что будет в случаях?
$a = 'строка';
$b = 0;
if ( $a == $b ) var_dump('равно');
else var_dump('не равно');
и
$a='125строка';
$b=125;
if ($a==$b) var_dump('равно');
else var_dump('не равно');
Кажется, что в первом и втором случаях будет «не равно» ?
А вот и нет 🙂 .
В двух случаях выражения будут «равно».
В PHP происходит автоматическое приведение типа.
Т.е. при сравнении с числом выражение вида «строка» приводится к 0,
а выражение вида «125строка» — к 125
————————————————————-
У меня возникла следующая ситуация.
Есть адрес вида www.ato.by/?value=ххх , где ххх — это число.
Мне потребовалось, в случае если ввели «/?value=хххстрока»,
делать автоматический 301 редирект на адрес «/?value=ххх»
В начале сделал так:
if ($_GET['value'] != intval($_GET['value'])) {
$URL= "http://site.ru/?value=" . intval($_GET['value'])
header ("Location: $URL");
}
— не работает по указанной выше причине.
Для избежания данной ситуаций требуется использовать конструкции:
- 1) функцию is_numeric
- 2) (string)$id == (string)(int)($id)
- 3) === — т.е. проверять совпадение типа и значения
Т.е. в моем случае следовало использовать:
if ( !is_numeric($_GET['value']) ) {
$URL= "http://site.ru/?value=" . intval($_GET['value'])
header ("Location: $URL");
}
или
if ( (string)$_GET['value'] != (string)(int)($_GET['value']) ) {
$URL= "http://site.ru/?value=" . intval($_GET['value'])
header ("Location: $URL");
}
т.к. число в $_GET[‘value’] должно ссылаться на определенный адйишник в базе данных, то я б сделал так:
if ( (int)$_GET[‘value’] <= 0 ) header ( "Location: http://site.ru/?value=" . intval($_GET['value']) );