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

Чим небезпечна функція extract і чому compact не завжди хороша ідея?

extract($array) створює змінні в поточній області видимості з ключів масиву:

extract(['name' => 'Оля', 'role' => 'admin']);
echo $name;   // 'Оля'

compact('name', 'role') - зворотне: збирає змінні в масив за іменами.

Чому extract небезпечний:

  • Перезапис змінних. За замовчуванням extract перезаписує наявні змінні. Якщо масив прийшов від користувача, нападник може підмінити будь-яку змінну функції:
$isAdmin = false;
extract($_POST);         // POST isAdmin=1 → $isAdmin = '1'
if ($isAdmin) { /* ... */ }

Історично це була реальна вразливість у CMS і плагінах.

  • Невидимі змінні. Читач коду не бачить, звідки взялася $role - її оголошення ніде немає. IDE й статичний аналіз теж не бачать.
  • Опечатки не ловляться: відсутній ключ просто не створить змінну, і код отримає «Undefined variable» далі.

Якщо extract таки потрібен: ніколи з даними від користувача і з прапорцем, що забороняє перезапис - extract($data, EXTR_SKIP).

compact безпечніший, але має свої мінуси:

return view('orders.show', compact('order', 'items', 'total'));
  • Імена змінних - рядки: перейменування змінної в IDE не оновить рядок у compact, і ключ зникне.
  • Відсутня змінна - лише попередження.

Явний масив читабельніший і надійніший при рефакторингу:

return view('orders.show', ['order' => $order, 'items' => $items, 'total' => $total]);

Де ці функції живуть легітимно: шаблонізатори (Blade під капотом робить extract даних подання в області видимості шаблону) - там джерело даних контрольоване, і це їхня пряма задача.

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

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