— В PHP приведение типов работает нормально, надо только включать здравый смысл.
— А чего там, просто сравниваешь и все…
— Ого, глюк какой-то в PHP, смотри, сравниваю два флоата, они должны быть одинаковые, а он мне говорит, что они не равны.
— А, ну когда число со строкой сравниваешь, перебирать надо, что сработает.
Слышали что-то подобное от коллег или может быть у самих возникали подобные ситуации? Тогда вот вам пятничный пост с примерами про приведение типов, как это работает с оператором ==.
Буду краток, дальше будут только примерчики. А к тебе, дорогой читатель, просьба. Некоторые ответы спрятаны под спойлер. Перед тем, как заглянуть в ответ под спойлером, попробуй ответить сам. За каждый правильный ответ заслуженно прибавляй себе по баллу. В конце поста в опросе не забудь проставить свой результат. Договорились?
Тогда поехали.
Начнем с чисел
Что может быть проще сравнения чисел, числа мы умеем сравнивать с детского сада.
Для порядка проверяем очевидное:
11 == 11
12 == 11
12 == 0xC
Как насчет такого сравнения?
12 == "0xC"
Попробуйте ответить
true. Да, тут значение в строке преобразовалось в целое с учетом системы счисления, здорово, правда?
А если так попробуем?
12 == 014
Чур не подглядываем, помните?
true. А как иначе? 014 — это же 12 в 8-ричной системе счисления.
Теперь так:
12 == "014"
Результат…
false. Те, кто хотел и тут true, умерьте свои требования, «0xC» преобразовалось в 12 и хватит.
И еще так:
14 == "014"
Равно…
true, вполне ожидаемо с учетом предыдущего примера.
Тут вроде все наглядно:
014 == "014"
Правильный ответ…
false, хотя чисто визуально это трудно заметить сходу, особенно, если читаешь чужой код.
Внимание:
0 == "0,9"
Ответ…
true, чего? А, ну да, так false: 0 == «0.9». Запятая посчиталась строковым символом и она и все после нее отбросилось.
Сравним такие значения:
"1e2" == "100"
Получим…
true, так как 1 умножить на 10 в квадрате равно 100.
0b11 == 3
А если 0b11 в строке?
"0b11" == 3
Сравниваем…
false, для 16-ричной системы это работает, а для двоичной — извините.
Теперь попробуем так:
2.333 == "2.333petrovich"
2.333 == "ivanovich2.333"
0 == "ivanovich2.333"
А тут попробуйте сами:
"2.33a" == "2.33b"
И получаем…
false, тут никакого преобразования нет, сравниваются строки.
233 == "233w1"
Почти тоже самое:
233 == "233e1"
Ответ…
false, да, кто заметил, тут 233 * 10.
"233" == "233w1"
233 == "233*1"
А если так скалькулировать?
233 == "233*2"
Вот…
Правильно, снова true, по аналогии с Петровичем.
0 == ""
Не подглядывайте, сперва сами:
"0" == ""
Пытаемся включить здравый смысл…
false, смиритесь.
"1.000000000000000123" == "1.000000000000000456"
Тоже два float в строках:
"2.000000000000000123" == "2.000000000000000456"
Догадались?
true, не удивляйтесь, с виду числа хоть и разные, но 2 == 2, тут все до 2 округлилось.
Булевы сравнения
Раз с числами все проще простого и все ответили правильно, то вот еще простые примерчики.
Сперва такой каламбур… вспомнился анекдот про Поручика, но пожалуй воздержусь.
"true" == true
"false" == true
"false" == false
"true" == false
Тут все просто и понятно.
true == "0"
true == "00"
true == 00
true == "00" + 0
А если так прибавить:
true == "01" + 0
То получим…
true, а тут уже к 1 прибавление.
true == "0x" + 0
Пробел пред нулем:
true == " 0"
Сверяемся…
true, хотя кто-то мог ожидать, что пробел отбросится и будет сравнение с нулем.
true == 0x0
true == "0x0"
true == "0.0"
true == " "
true == []
true == [0]
А если так?
true == [[]]
Проверяем…
true, тут массив что-то себе содержит, пустой массив.
NULL
Позвольте еще несколько сравнений, теперь с null.
null == false
null == 0
false == "0"
Попробуйте догадаться по аналогии:
null == "0"
Получаем…
false, видимо, надо просто запомнить.
null == []
null == [0]
Массивы
Ну и для особо любознательных — сравнения массивов.
Тут надеюсь, сами догадаетесь, только не подглядывайте:
[] == 0
Сверяем…
Точно, false, хотя null == 0 и [] == null.
[0] == 0
В документации сказано, что "$a == $b — TRUE в случае, если $a и $b содержат одни и те же пары ключ/значение".
Проверим, как именно работает это утверждение. тем более, что в доке ничего ни сказано про то, как сравниваются ключи.
[1 => 1] == [1 => 1]
[1 => 1] == ["1" => 1]
[1 => 1] == ["0x1" => 1]
array_keys([1 => 1]) == array_keys(["0x1" => 1])
Зато:
[1 => 1] == [1 => "0x1"]
Загадочка
И на десерт загадочка (загадка не от меня, коллега однажды ее мне дал).
Может ли когда-либо выполниться условие $x == 1 && $x == 2, если может, то когда, если нет, то почему?
А как-же резюме?
А какое тут резюме, табурет с двумя ножками вполне может быть использован по назначению. Более того, он имеет свои положительные стороны, например, помогает держать в тонусе вестибулярный аппарат и ягодицы. Так что читаем доки, набиваем шишки и все будет хорошо.