PHPJuniorTechnical
В чём разница между == и === в PHP?
== сравнивает значения с приведением типов ("1" == 1 → true), === требует совпадения и типа, и значения. Используйте === везде, где важна корректность.
== и === в PHP
== — оператор нестрогого (loose) сравнения: PHP приводит оба операнда к общему типу перед сравнением. === — оператор строгого (strict) сравнения: значения должны совпадать и иметь одинаковый тип.
Как работает приведение типов при ==
PHP следует правилам таблицы приведения типов (type juggling). Основные случаи:
- Число и строка: строка конвертируется в число.
"1" == 1→true. - Строка и
null: null конвертируется в пустую строку."" == null→true. - Булево и что угодно: второй операнд конвертируется в bool.
"0" == false→true. - В PHP 7 и ниже:
0 == "abc"→true(строка без числового префикса → 0). В PHP 8 это исправлено — строка конвертируется в число только если она числовая, иначе 0 сравнивается со строкой как строка →false.
Примеры ловушек
<?php
// PHP 7 и ранее (!) — все следующие == дают true
var_dump(0 == 'foo'); // true в PHP 7, FALSE в PHP 8
var_dump(0 == ''); // true в PHP 7, FALSE в PHP 8
var_dump("1" == "01"); // true (числовые строки)
var_dump("10" == "1e1"); // true (научная нотация)
var_dump(100 == "1e2"); // true
var_dump(null == false); // true
var_dump(null == 0); // true
var_dump(null == ""); // true
var_dump(null == "0"); // FALSE! null == 0 == true, но "0" != ""
// === всегда предсказуем
var_dump("1" === 1); // false (разные типы)
var_dump(null === false); // false
var_dump(1 === 1); // true
var_dump("01" === "01"); // true
Сравнение объектов
<?php
class Point { public function __construct(public int $x, public int $y) {} }
$a = new Point(1, 2);
$b = new Point(1, 2);
$c = $a;
var_dump($a == $b); // true — одинаковый класс и значения свойств
var_dump($a === $b); // false — разные экземпляры
var_dump($a === $c); // true — одна и та же ссылка
Когда использовать ==
Практически никогда в коде, где важна корректность. Единственный распространённый случай — сравнение с null через is_null() или ?? null лучше явных проверок. Предпочитайте === и !== везде.
Сортировка и spaceship-оператор
<?php
// usort с нестрогим сравнением может давать неожиданный порядок
$arr = ["10", "9", "100"];
usort($arr, fn($a, $b) => $a - $b); // числовое сравнение строк
// Лучше явно: fn($a, $b) => (int)$a <=> (int)$b
Подводные камни
- Знаменитая ловушка PHP 7:
0 == "password"даётtrue— это открывало уязвимости в аутентификации при сравнении хешей через==. В PHP 8 поведение изменилось, но код может работать на старом PHP. switchиспользует нестрогое сравнение (==) — используйтеmatch(строгое) в PHP 8+.in_array($needle, $haystack)по умолчанию нестрогий — передавайтеtrueтретьим аргументом для строгой проверки.array_search()тоже нестрогий по умолчанию.- Сравнение строк с числами в PHP 7:
"123abc" == 123→true(числовой префикс парсится). null == false == 0 == "" == "0"— цепочка transitive-подобных равенств при==нарушает ожидания.- Сравнение объектов через
==сравнивает свойства, но при наличии приватных свойств или магических методов результат непредсказуем. - Смешение
==и!==в одном выражении — источник трудноуловимых багов; выберите один стиль для проекта.
Common mistakes
- Сводить loose vs strict comparison к названию метода без lifecycle и failure path.
- Игнорировать модель runtime: интерпретируемый runtime PHP 8.x, обычно запускаемый как отдельный запрос в FPM, CLI или worker-процессе.
- Не отделять validation, authorization, transaction boundary и business logic.
- Менять похожие API местами без учёта семантики ошибок и ownership.
What the interviewer is testing
- Объясняет loose vs strict comparison через конкретную точку lifecycle в PHP.
- Приводит корректный минимальный пример без вымышленных методов или callbacks.
- Называет edge cases: пустые значения, ошибки, транзакции, безопасность или concurrency.