Cá nhân tôi nghĩ rằng đoạn mã đó vẫn khá tệ vì bạn không bình luận về những gì nó đang làm. Nó cũng không kiểm tra tính hợp lệ của đầu vào, khiến nó rất dễ hỏng.
Tôi cũng cảm thấy rằng, vì 95% (hoặc nhiều hơn) việc sử dụng eval là nguy hiểm, nên việc tiết kiệm thời gian tiềm năng nhỏ mà nó có thể cung cấp trong các trường hợp khác không đáng để bạn bỏ qua việc sử dụng nó. Thêm vào đó, sau này bạn sẽ phải giải thích cho tay sai của mình tại sao việc sử dụng eval của bạn là tốt và của chúng là xấu.
Và, tất nhiên, PHP của bạn trông giống như Perl;)
Có hai vấn đề chính với eval (), (như một kịch bản "tấn công tiêm"):
1) Nó có thể gây hại 2) Nó có thể chỉ bị sập
và một thứ mang tính xã hội hơn là kỹ thuật:
3) Nó sẽ cám dỗ mọi người sử dụng nó một cách không thích hợp như một lối tắt ở những nơi khác
Trong trường hợp đầu tiên, bạn gặp rủi ro (hiển nhiên, không phải khi bạn đang đánh giá một chuỗi đã biết) khi thực thi mã tùy ý. Tuy nhiên, đầu vào của bạn có thể không được xác định hoặc cố định như bạn nghĩ.
Nhiều khả năng (trong trường hợp này) bạn sẽ chỉ gặp sự cố và chuỗi của bạn sẽ kết thúc với một thông báo lỗi vô cớ. IMHO, tất cả mã phải lỗi càng gọn gàng càng tốt, lỗi mà nó sẽ tạo ra một ngoại lệ (là dạng lỗi dễ xử lý nhất).
Tôi gợi ý rằng, trong ví dụ này, bạn đang viết mã theo cách ngẫu nhiên chứ không phải mã theo hành vi. Có, câu lệnh SQL enum (và bạn có chắc là trường đó là enum không? - bạn đã gọi đúng trường của bảng bên phải của phiên bản cơ sở dữ liệu phù hợp chưa? Nó có thực sự trả lời không?) Giống như cú pháp khai báo mảng trong PHP, nhưng tôi đề nghị những gì bạn thực sự muốn làm không phải là tìm con đường ngắn nhất từ đầu vào đến đầu ra, mà là giải quyết nhiệm vụ được chỉ định:
- Xác định rằng bạn có một enum
- Trích xuất danh sách bên trong
- Giải nén các giá trị danh sách
Đó gần như là những gì tùy chọn của bạn làm, nhưng tôi sẽ giới thiệu một số if và nhận xét xung quanh nó để rõ ràng và an toàn (ví dụ: nếu kết quả đầu tiên không khớp, hãy ném ngoại lệ hoặc đặt kết quả null).
Vẫn có một số vấn đề có thể xảy ra với dấu phẩy hoặc dấu ngoặc kép và bạn có thể nên giải nén dữ liệu sau đó hủy trích dẫn, nhưng ít nhất nó cũng coi dữ liệu là dữ liệu chứ không phải là mã.
Với preg_version, kết quả tồi tệ nhất của bạn có thể là $ result = null, với phiên bản eval, kết quả tồi tệ nhất là không xác định, nhưng ít nhất là một sự cố.
$result = array(); preg_replace_callback('#^enum\s*\(\s*\'|\'\s*\)\s*$#', function($m) use($result) { $result[] = $m[1]; }, $type);