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

Junior: питання на співбесіді з теми «Масиви й рядки»

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

4 питання

Усі три обходять масив і викликають функцію для кожного елемента, але повертають різне:

  • array_map - новий масив тієї ж довжини, кожен елемент перетворено.
  • array_filter - лише ті елементи, для яких функція повернула true. Ключі зберігаються.
  • array_reduce - одне значення, накопичене з усіх елементів.
$prices = [100, 250, 40];

array_map(fn (int $p): int => $p * 2, $prices);          // [200, 500, 80]
array_filter($prices, fn (int $p): bool => $p > 50);      // [0 => 100, 1 => 250]
array_reduce($prices, fn (int $sum, int $p): int => $sum + $p, 0); // 390

Пастки, про які питають:

  • Порядок аргументів різний: у array_map спершу функція, у array_filter - масив. Плутають постійно.
  • Після array_filter ключі «дірчасті» ([0, 2, 5]), і json_encode перетворить такий масив на об'єкт. Допомагає array_values().
  • array_filter без функції прибирає всі «порожні» значення - разом із 0 і '0', що інколи несподівано.

Жодна з функцій не змінює початковий масив - усі повертають новий.

Докладніше в документації: array_map

Рядок у PHP - це послідовність байтів, а не символів. strlen() рахує байти. У UTF-8 кожна кирилична літера займає 2 байти, тож «привіт» - 12 байтів.

strlen('привіт');        // 12
mb_strlen('привіт');     // 6
mb_substr('привіт', 0, 3); // 'при'
substr('привіт', 0, 3);  // зламаний символ: 'п' і половина 'р'

Правило: для тексту, де можуть бути не лише латинські літери, використовуйте mb_*-функції: mb_strlen, mb_substr, mb_strtoupper, mb_str_split. Байтові функції зріжуть символ посередині, і в результаті з'явиться «�».

Нюанси:

  • mb_* рахують кодові точки Unicode. Емодзі з модифікатором шкіри чи прапор складаються з кількох точок, і для «видимих символів» потрібен grapheme_strlen() з розширення intl.
  • strlen() не помилка - він потрібен, коли важливі саме байти: розмір тіла запиту, обмеження колонки в байтах.
  • У Laravel Str::length(), Str::limit() уже працюють через mb_*.

Докладніше в документації: mb_strlen

Усі три перевіряють «чи є значення», але з різною семантикою:

  • isset($a['key']) - ключ існує і значення не null.
  • array_key_exists('key', $a) - ключ існує, хай навіть зі значенням null.
  • empty($a['key']) - ключа немає або значення «порожнє»: null, false, 0, 0.0, '', '0', [].
$data = ['name' => '', 'phone' => null, 'age' => 0];

isset($data['phone']);              // false - значення null
array_key_exists('phone', $data);   // true  - ключ є
empty($data['age']);                // true  - 0 вважається порожнім
empty($data['name']);               // true
isset($data['missing']);            // false, без попередження

Де це важливо:

  • PATCH-запит до API: {"phone": null} означає «очистити телефон», а відсутній ключ - «не чіпати». Розрізнити допоможе лише array_key_exists (у Laravel - $request->has('phone') проти $request->filled('phone')).
  • empty('0') - true. Рядок «0» у формі (кількість, рейтинг) стане «порожнім». Для чисел краще явні перевірки.
  • Вкладені ключі: isset($a['user']['address']['city']) безпечно перевіряє весь ланцюжок без попереджень.

isset і empty - мовні конструкції, а не функції: не кидають попереджень на неіснуючих змінних і ключах. Через це їх легко використати для приховування опечаток - isset($usr) мовчки поверне false.

Для об'єктів: isset($obj->prop) для неініціалізованої типізованої властивості - false; property_exists() перевіряє, чи оголошена властивість у класі.

Докладніше в документації: array_key_exists

Основні функції:

explode(',', 'php,laravel,vue');          // ['php', 'laravel', 'vue']
explode(',', 'a,b,c,d', 2);               // ['a', 'b,c,d'] - не більше 2 частин
implode(', ', ['php', 'laravel']);        // 'php, laravel'

str_split('abcdef', 2);                   // ['ab', 'cd', 'ef'] - байтами!
mb_str_split('привіт', 2);                // ['пр', 'ив', 'іт'] - символами

preg_split('/[\s,;]+/', 'php, laravel; vue', -1, PREG_SPLIT_NO_EMPTY);
// ['php', 'laravel', 'vue'] - кілька роздільників

Типові пастки:

  • Порожній рядок: explode(',', '') повертає [''] - масив з одним порожнім елементом, а не порожній масив. Для введення користувача часто потрібне array_filter(array_map('trim', explode(',', $input))).
  • Пробіли: explode(',', 'a, b') дає ['a', ' b'] - з пробілом. Звідси array_map('trim', ...).
  • Кирилиця: str_split ділить байти й ламає багатобайтові символи. Для тексту - mb_str_split.
  • CSV не розбирають через explode: значення можуть містити коми в лапках ("Київ, Україна"). Для цього str_getcsv() чи SplFileObject з READ_CSV.

У Laravel зручніше через Str і колекції:

Str::of('php, laravel , vue')->explode(',')->map(fn ($s) => trim($s))->filter();

Докладніше в документації: explode