Особисто я думаю, що код все ще досить злий, тому що ви не коментуєте, що він робить. Він також не перевіряє свої дані на достовірність, роблячи його дуже крихким.
Я також вважаю, що, оскільки 95% (або більше) випадків використання eval є активно небезпечними, мала економія часу, яку він може забезпечити в інших випадках, не варта потурати поганій практиці його використання. Крім того, згодом вам доведеться пояснити своїм прихильникам, чому ваше використання eval добре, а їхнє погане.
І, звичайно, ваш PHP в підсумку виглядає як Perl;)
Є дві ключові проблеми з eval (), (як сценарій "ін'єкції"):
1) Це може завдати шкоди 2) Це може просто розбитися
і більш соціальний, ніж технічний:
3) Це спокусить людей використовувати його неналежним чином як ярлик в іншому місці
У першому випадку ви ризикуєте (очевидно, не тоді, коли оцінюєте відомий рядок) довільного виконання коду. Однак ваші введені дані можуть бути не такими відомими або фіксованими, як ви думаєте.
Швидше за все (у цьому випадку) ви просто вийдете з ладу, і ваш рядок закінчиться безвідмовно незрозумілим повідомленням про помилку. IMHO, весь код повинен виходити з ладу якомога акуратніше, у разі відмови він повинен видавати виняток (як найбільш обробну форму помилки).
Я б припустив, що в цьому прикладі ви кодуєте випадково, а не кодуєте поведінку. Так, оператор перерахування SQL (і чи впевнені ви в переліку цього поля? - чи викликали ви праве поле правої таблиці потрібної версії бази даних? Чи справді відповідало?) Виглядає як синтаксис оголошення масиву в PHP, але я б порадив, що ви дійсно хочете зробити, це не знайти найкоротший шлях від входу до виводу, а скоріше вирішити вказане завдання:
- Визначте, що у вас є перелік
- Витягніть внутрішній список
- Розпакуйте значення списку
Що приблизно те, що робить ваш варіант, але я б обгорнув деякі if та коментарі навколо нього для ясності та безпеки (наприклад, якщо перший збіг не збігається, викиньте виняток або встановіть нульовий результат).
Існують ще деякі можливі проблеми з екранованими комами або лапками, і, ймовірно, вам слід розпакувати дані, а потім зняти цитати, але це принаймні трактує дані як дані, а не як код.
З preg_version вашим найгіршим результатом, швидше за все, буде $ result = null, з версією eval найгірший невідомий, але принаймні збій.
$result = array(); preg_replace_callback('#^enum\s*\(\s*\'|\'\s*\)\s*$#', function($m) use($result) { $result[] = $m[1]; }, $type);