Всем известно что в PHP нет строгой типизации. Вроде бы все хорошо, но! Иногда нестрогая типизация может привести к критическим ошибкам в ваших приложениях. В данной статье я приведу пару таблиц приведения типов данных в PHP которую каждый разработчик должен держать в голове.
Вот хорошая таблица из официальных доков отображающая нестрогое сравнение (немного урезал):
TRUE | FALSE | 1 | 0 | NULL | array() | «txt» | «» | |
TRUE | FALSE | TRUE | FALSE | FALSE | FALSE | TRUE | FALSE | |
FALSE | FALSE | FALSE | TRUE | TRUE | TRUE | FALSE | TRUE | |
1 | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | |
0 | FALSE | TRUE | FALSE | TRUE | FALSE | TRUE | TRUE | |
NULL | FALSE | TRUE | FALSE | TRUE | TRUE | FALSE | TRUE | |
array() | FALSE | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | |
«txt» | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | |
«» | FALSE | TRUE | FALSE | TRUE | TRUE | FALSE | FALSE |
Но самое интересное на мой взгляд это то как PHP приводит строки к числу. Вот составил таблицу:
«» | «text» | «1text» | «0text» | «1text1» | «1.1text» | |
intval | 0 | 0 | 1 | 0 | 1 | 1 |
floatval | 0 | 0 | 1 | 0 | 1 | 1.1 |
Как видно из этой таблицы, при приведении строки к числу, PHP считает числом всю строку до первого «нечислового» символа. Наплевательское отношение к этому приведению может привести к критическим ошибкам.
К примеру уязвимый код из одной известной CMS:
if($_GET["module_id"]==2){
mysql_query("SELECT * FROM modules WHERE id='".$_GET["module_id"]."'");
//...
}
По замыслу разработчиков $_GET["module_id"]
должно быть равна числу 2. Но они забыли что любая строка приводится к числу. А это привело к возможности провести атаку типа SQL injection:
http://host/path/script.php?module_id=2' -- d
Вообщем все это я к чему пишу то. При разработке любых скриптов надо давать себе отчет в том зачем в одном месте вы используете строгое сравнение (===) а в другом месте нестрогое сравнение (==). И необходимо постоянно держать в памяти тот факт, что в PHP используется нестрогая типизация (особенно это сложно тем кто перешел на PHP с других языков программирования).
Всё понятн и логично.
Единстенное, чего никогда не понимал — Где логика, почему
"txt" == 0
Может тут кто пояснит?
Потому что при сравнении строка приводится к числу, к примеру:
Т.е. грубо говоря из строки берутся начальные символы до первого «не числового» символа. Естественно если числовых символов в начале строки нет, то такая строка приведется к «int 0».
Ну и дальше все верно «int 0==int 0»
Надеюсь я смог пояснить)