Приведение типов в PHP == табурет о двух ножках?

image— В PHP приведение типов работает нормально, надо только включать здравый смысл.— А чего там, просто сравниваешь и все…— Ого, глюк какой-то в PHP, смотри, сравниваю два флоата, они должны быть одинаковые, а он мне говорит, что они не равны.— А, ну когда число со строкой сравниваешь, перебирать надо, что сработает.

Слышали что-то подобное от коллег или может быть у самих возникали подобные ситуации? Тогда вот вам пятничный пост с примерами про приведение типов, как это работает с оператором ==.

Буду краток, дальше будут только примерчики. А к тебе, дорогой читатель, просьба. Некоторые ответы спрятаны под спойлер. Перед тем, как заглянуть в ответ под спойлером, попробуй ответить сам. За каждый правильный ответ заслуженно прибавляй себе по баллу. В конце поста в опросе не забудь проставить свой результат. Договорились? Тогда поехали.

Начнем с чиселЧто может быть проще сравнения чисел, числа мы умеем сравнивать с детского сада.Для порядка проверяем очевидное:

11 == 11 // true, воистину 12 == 11 // false, само собой 12 == 0xC // true, сравниваем с 16-ричным Как насчет такого сравнения? 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 // true, 0b — это относится к двоичной системе А если 0b11 в строке? »0b11» == 3 Сравниваем… false, для 16-ричной системы это работает, а для двоичной — извините.

Теперь попробуем так: 2.333 == »2.333petrovich» // true, тут Петрович в конце строки и поэтому исключается из сравнения. 2.333 == «ivanovich2.333» // false, а тут Иванович вначале, поэтому сравнение идет со строкой. 0 == «ivanovich2.333» // true, строка равна нулю. А тут попробуйте сами:

»2.33a» == »2.33b» И получаем… false, тут никакого преобразования нет, сравниваются строки.

233 == »233w1» // true, по аналогии с Петровичем Почти тоже самое: 233 == »233e1» Ответ… false, да, кто заметил, тут 233×10.

»233» == »233w1» // false 233 == »233×1» // true А если так скалькулировать? 233 == »233×2» Вот… Правильно, снова true, по аналогии с Петровичем.

0 == » // true Не подглядывайте, сперва сами: »0» == » Пытаемся включить здравый смысл… false, смиритесь.

»1.000000000000000123» == »1.000000000000000456» // false, логично, разные ж числа. Тоже два float в строках: »2.000000000000000123» == »2.000000000000000456» Догадались? true, не удивляйтесь, с виду числа хоть и разные, но 2 == 2, тут все до 2 округлилось.

Булевы сравнения Раз с числами все проще простого и все ответили правильно, то вот еще простые примерчики.Сперва такой каламбур… вспомнился анекдот про Поручика, но пожалуй воздержусь.

«true» == true // true «false» == true // true, строка равна true «false» == false // false, строка равна true «true» == false // false, строка равна true Тут все просто и понятно. true == »0» // false, тут уже идет сравнение не со строкой, а с нулем true == »00» // true, а тут со строкой… true == 00 // false true == »00» + 0 // false, тут к строке с нулем 0 прибавили А если так прибавить: true == »01» + 0 То получим… true, а тут уже к 1 прибавление.

true == »0x» + 0 // false Пробел пред нулем: true == » 0» Сверяемся… true, хотя кто-то мог ожидать, что пробел отбросится и будет сравнение с нулем.

true == 0×0 // false true == »0×0» // true, так-то, тут уже не 0, а строка true == »0.0» // true, и тут строка true == » » // true true == [] // false, пустой массив — это false true == [0] //, а массив с нулем — true А если так? true == [[]] Проверяем… true, тут массив что-то себе содержит, пустой массив.

NULL Позвольте еще несколько сравнений, теперь с null. null == false // true, null == 0 // true, false == »0» // true, Попробуйте догадаться по аналогии: null == »0» Получаем… false, видимо, надо просто запомнить.

null == [] // true, так как массив пустой null == [0] // false, не пустой массив все-таки Массивы Ну и для особо любознательных — сравнения массивов.Тут надеюсь, сами догадаетесь, только не подглядывайте:

[] == 0 Сверяем… Точно, false, хотя null == 0 и [] == null.

[0] == 0 // false, В документации сказано, что »$a == $b — TRUE в случае, если $a и $b содержат одни и те же пары ключ/значение».Проверим, как именно работает это утверждение. тем более, что в доке ничего ни сказано про то, как сравниваются ключи. [1 => 1] == [1 => 1] // true [1 => 1] == [»1» => 1] // true, при этом: [1 => 1] == [»0×1» => 1] // false, при том, что если отдельно сравнить ключи таким образом: array_keys ([1 => 1]) == array_keys ([»0×1» => 1]) // true Зато: [1 => 1] == [1 => »0×1»] // true Загадочка И на десерт загадочка (загадка не от меня, коллега однажды ее мне дал).Может ли когда-либо выполниться условие $x == 1 && $x == 2, если может, то когда, если нет, то почему? А как-же резюме? А какое тут резюме, табурет с двумя ножками вполне может быть использован по назначению. Более того, он имеет свои положительные стороны, например, помогает держать в тонусе вестибулярный аппарат и ягодицы. Так что читаем доки, набиваем шишки и все будет хорошо.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

© Habrahabr.ru