Osobiście uważam, że ten kod jest nadal dość zły, ponieważ nie komentujesz tego, co robi. Nie testuje również swoich danych wejściowych pod kątem ważności, co czyni go bardzo delikatnym.
Uważam również, że ponieważ 95% (lub więcej) zastosowań eval jest aktywnie niebezpiecznych, niewielka potencjalna oszczędność czasu, jaką może on zapewnić w innych przypadkach, nie jest warta oddawania się złej praktyce jego używania. Poza tym będziesz musiał później wyjaśnić swoim sługom, dlaczego twoje użycie eval jest dobre, a ich złe.
I, oczywiście, twój PHP wygląda jak Perl;)
Istnieją dwa kluczowe problemy z eval () (jako scenariusz „ataku iniekcyjnego”):
1) Może spowodować obrażenia 2) Może po prostu się zawiesić
i bardziej społeczny niż techniczny:
3) Będzie to kusić ludzi do niewłaściwego używania go jako skrótu w innym miejscu
W pierwszym przypadku ryzykujesz (oczywiście nie wtedy, gdy oceniasz znany ciąg znaków) wykonania dowolnego kodu. Twoje dane wejściowe mogą jednak nie być tak znane lub ustalone, jak myślisz.
Bardziej prawdopodobne jest (w tym przypadku) awarię, a ciąg znaków zakończy się nieuzasadnionym niejasnym komunikatem o błędzie. IMHO, cały kod powinien zawieść tak starannie, jak to możliwe, aw przypadku niepowodzenia powinien zgłosić wyjątek (jako najłatwiejszą do obsługi formę błędu).
Sugerowałbym, że w tym przykładzie kodujesz przez przypadek, a nie na zachowanie. Tak, instrukcja wyliczenia SQL (i czy na pewno wyliczenie tego pola? - czy wywołałeś właściwe pole odpowiedniej tabeli odpowiedniej wersji bazy danych? Czy faktycznie odpowiedziała?) Wygląda jak składnia deklaracji tablicy w PHP, ale sugerowałbym, że naprawdę nie chcesz znaleźć najkrótszej ścieżki od wejścia do wyjścia, ale raczej zająć się określonym zadaniem:
- Zidentyfikuj, że masz wyliczenie
- Wyodrębnij listę wewnętrzną
- Rozpakuj wartości listy
To mniej więcej to, co robi twoja opcja, ale zawinąłbym wokół niej kilka „if” i komentarzy dla jasności i bezpieczeństwa (np. Jeśli pierwszy mecz nie pasuje, wyrzuć wyjątek lub ustaw wynik zerowy).
Nadal istnieją pewne możliwe problemy z przecinkami lub cudzysłowami i prawdopodobnie powinieneś rozpakować dane, a następnie usunąć je z cudzysłowu, ale przynajmniej traktuje dane jako dane, a nie jako kod.
W wersji preg_version najgorszym wynikiem będzie prawdopodobnie $ result = null, aw wersji eval najgorszy jest nieznany, ale przynajmniej awaria.
$result = array(); preg_replace_callback('#^enum\s*\(\s*\'|\'\s*\)\s*$#', function($m) use($result) { $result[] = $m[1]; }, $type);