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

Junior: питання на співбесіді з теми «PHP 8+»

Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.

3 питання

Іменовані аргументи (PHP 8.0) дозволяють передавати аргументи за іменем параметра, а не лише за позицією.

// Позиційно: що означає true? а 0?
htmlspecialchars($text, ENT_QUOTES, 'UTF-8', false);

// Іменовано
htmlspecialchars($text, double_encode: false);

str_pad(string: 'x', length: 5, pad_type: STR_PAD_LEFT);

Переваги:

  • Читабельність для булевих прапорців і «магічних» чисел: new Invoice(paid: true, sendEmail: false) замість new Invoice(true, false).
  • Пропуск необов'язкових параметрів: передати лише останній, не перелічуючи значення за замовчуванням для всіх попередніх.
  • Будь-який порядок: іменовані аргументи можна передавати не в порядку оголошення.
  • Разом з constructor promotion дають зручні value objects і DTO: new Address(city: 'Київ', street: 'Хрещатик').

Правила:

  • Спершу позиційні, потім іменовані: f(1, b: 2) - так; f(a: 1, 2) - ні.
  • Один параметр не можна передати двічі.
  • Невідоме ім'я - помилка.
  • Для variadic-параметрів (...$args) іменовані аргументи збираються в масив з рядковими ключами.

Застереження для авторів бібліотек: з іменованими аргументами назва параметра стає частиною публічного API. Перейменування $str на $string у новій версії зламає код, що викликав функцію іменовано. Тому в бібліотеках назви параметрів змінюють так само обережно, як і назви методів.

Докладніше в документації: Іменовані аргументи

First-class callable syntax (PHP 8.1) створює замикання (Closure) з функції чи методу, записавши (...) замість аргументів.

$length = strlen(...);
$length('привіт');                       // 12

$format = $this->formatPrice(...);       // метод об'єкта
$create = User::create(...);             // статичний метод

array_map(trim(...), $lines);
array_filter($users, $this->isActive(...));

Чим краще за старі способи передати функцію:

array_map('trim', $lines);                        // рядок
array_filter($users, [$this, 'isActive']);        // масив
array_filter($users, fn ($u) => $this->isActive($u));   // обгортка
  • Перевіряється одразу: якщо методу не існує чи він недоступний, помилка виникне в момент створення, а не десь пізніше при виклику.
  • Рефакторинг і IDE: «перейти до визначення» і перейменування методу працюють - на відміну від імені в рядку 'isActive'.
  • Видимість: $this->privateMethod(...) усередині класу створює замикання, яке можна передати назовні й викликати, - а [$this, 'privateMethod'] поза класом не спрацює.
  • Статичний аналіз бачить сигнатуру й перевіряє типи.

Обмеження: не працює з nullsafe ($obj?->method(...) - помилка) і з new Foo(...).

PHP 8.5 доповнив це оператором конвеєра |>, який передає значення в callable праворуч: $text |> trim(...) |> strtoupper(...).

Докладніше в документації: First-class callable syntax

PHP 8.0 (листопад 2020) - один з найбільших релізів мови. Головне:

Мова:

  • Іменовані аргументи - f(limit: 10).
  • Constructor property promotion - властивості в параметрах конструктора.
  • Union-типи - int|string, плюс тип mixed і тип повернення static.
  • match - вираз зі строгим порівнянням і без провалювання.
  • Nullsafe-оператор ?->.
  • Атрибути - #[Route('/users')] замість анотацій у PHPDoc.
  • throw як вираз - $user ?? throw new NotFound().
  • catch без змінної - catch (TimeoutException).

Суворіша поведінка:

  • Порівняння числа з рядком: 0 == 'abc' тепер false.
  • Помилки замість попереджень: багато внутрішніх функцій кидають TypeError чи ValueError при неправильних аргументах, а арифметика з нечисловим рядком - TypeError.
  • Узгоджені сигнатури вбудованих функцій і перевірка сумісності методів при успадкуванні.

Нові функції: str_contains(), str_starts_with(), str_ends_with(), get_debug_type(), fdiv().

Продуктивність: JIT-компілятор (для обчислювальних задач; типовому веб-застосунку дає небагато) і загальні оптимізації рушія.

Чому це важливо на співбесіді: більшість сучасного PHP-коду спирається саме на ці можливості, а суворіші правила PHP 8 - часта причина проблем при оновленні старих застосунків з PHP 7.

Докладніше в документації: Реліз PHP 8.0