Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як PHP 8 приводить числові рядки в арифметиці й порівняннях?

PHP 8 переробив правила приведення рядків до чисел, зробивши їх суворішими й передбачуванішими.

Три види рядків:

  • Числовий - лише число, з можливими пробілами на початку й у кінці: '42', ' 3.14 ', '1e3'.
  • З числовим початком - число, а за ним інші символи: '5 apples'.
  • Нечисловий - усе інше: 'abc', ''.

В арифметиці:

'42' + 1;          // 43
'5 apples' + 1;    // 6 і Warning: A non-numeric value encountered
'abc' + 1;         // TypeError

У PHP 7 'abc' + 1 давав 1 з попередженням - помилка тихо перетворювалася на нуль. Тепер це виняток.

У порівнянні ==:

  • два числові рядки порівнюються як числа: '1e3' == '1000' - true, '10' == '010' - true;
  • число з числовим рядком - як числа;
  • число з нечисловим рядком - як рядки: 0 == 'abc' - false у PHP 8 (у PHP 7 - true, бо 'abc' ставав нулем).

Під declare(strict_types=1) скалярні параметри функцій не приводяться взагалі: int $id не прийме '5' - буде TypeError. Арифметичних операторів і порівнянь strict_types не стосується.

Практичні висновки:

  • Дані з форм і запитів - завжди рядки. Приводьте їх явно й валідуйте ((int), filter_var($v, FILTER_VALIDATE_INT), правила валідації Laravel), а не покладайтеся на неявне приведення.
  • === замість ==, особливо для значень від користувача: «магічні хеші» на кшталт '0e123' == '0e456' (обидва - нуль у науковій нотації) досі true.
  • Для перевірки «чи це число» - is_numeric() (приймає числові рядки) чи ctype_digit() (лише цифри, без знаку й крапки).

Докладніше в документації: Числові рядки

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання