TGViewer
Библиотека пхпшника | PHP, Laravel, Symfony, CodeIgniter Библиотека пхпшника | PHP, Laravel, Symfony, CodeIgniter @phpproglib · 10.5K subscribers
Post #6013 2.01K
🎲 Простой скрипт на PHP: что будет — true или false?
$a = 12345678901234567890;
$b = $a + 1;
var_dump($a === $b);


🔍 На первый взгляд: $b = $a + 1 → два разных числа, значит === должен вернуть false.
Но PHP выведет true — значения «слипаются».

🧠 Почему так?

В PHP есть два числовых типа: int и float (double, по стандарту IEEE-754).

Если в коде стоит очень большое целое число, которое не помещается в диапазон int (на 64-битной системе около ±9.22e18), PHP автоматически парсит его как float.

В нашем примере оба литерала слишком большие → оба превращаются в float ещё на этапе разбора кода.

float хранит числа с ~15–17 значимыми цифрами. На значениях порядка 10¹⁹ шаг между двумя смежными представленными числами (ULP) может быть около 2048!

Разница в 1 между $a и $a + 1 слишком мала, чтобы быть «видимой» в представлении float. В итоге оба числа записываются как одно и то же значение.

При строгом сравнении === PHP сравнивает тип и внутреннее двоичное представление — и они совпадают → true.

⚠️ Где это может подвести в жизни

ID из БД или API
Длинные идентификаторы (BIGINT) попадают в PHP как числа → уязвимость к потере точности.

json_decode
Без JSON_BIGINT_AS_STRING большие числа могут превратиться в float.

Ключи массивов
Если использовать очень большое число как ключ, он может оказаться float, потом приведён к int, и несколько ключей «слипнутся» в один.

Сравнения и безопасность
Два разных числа могут быть признаны равными, что приводит к неожиданному поведению.

✅ Как защититься

Передавайте идентификаторы как строки, а не числа.

При декодировании JSON используйте:
json_decode($json, false, 512, JSON_BIGINT_AS_STRING);


Для операций с большими числами — bcmath, gmp или аналоги:
bccomp("12345678901234567890", "12345678901234567899");  // -1  
bcadd("99999999999999999999", "1"); // "100000000000000000000"


Валидируйте входные данные: не приводите строку к int, если она вне допустимого диапазона.

На фронтенде (JavaScript) тоже осторожно: безопасная зона — до ±(2^53 − 1). Всё, что больше — отправляйте строкой.

💡 PHP «слипает» очень большие целые числа в float, и на больших значениях шаг между числами становится большим. Поэтому два разных литерала могут превратиться в одно и то же значение.

🔗 Хабр

Библиотека пхпшника
  • 👍 27
  • ❤ 1
More from @phpproglib
  1. Sep 25, 2026🌞 PHP умеет искать в массиве без foreach В PHP 8.4 появились array_find(), array_find_key…
  2. Sep 24, 2026👍 5 способов встроить AI в Laravel Laravel AI SDK позволяет добавлять AI-функции прямо в…
  3. Sep 23, 2026🛠 Symfony 8.2 научился автоматически генерировать JSON Schema для конфигурации приложения…
  4. Sep 23, 2026🚀 Свежий релиз Laravel 13 с набором улучшений и исправлений ✅ добавлена поддержка valkey:…
  5. Sep 21, 2026⚡️ PHP 8.6 выйдет 19 ноября 2026 года. Сейчас версия находится в beta. Самые заметные изме…
  6. Sep 20, 2026❓ Какие существуют проблемы в многопоточной среде? Основные проблемы многопоточности: 1️⃣…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →