โดยส่วนตัวแล้วฉันคิดว่าโค้ดนั้นยังค่อนข้างชั่วร้ายเพราะคุณไม่ได้แสดงความคิดเห็นว่ามันทำอะไร นอกจากนี้ยังไม่ได้ทดสอบปัจจัยการผลิตเพื่อความถูกต้องทำให้เปราะบางมาก
ฉันยังรู้สึกว่าเนื่องจาก 95% (หรือมากกว่า) ของการใช้ eval เป็นอันตรายอย่างมากการประหยัดเวลาเล็กน้อยที่อาจเกิดขึ้นในกรณีอื่น ๆ จึงไม่คุ้มค่ากับการปฏิบัติที่ไม่ดีในการใช้งาน นอกจากนี้คุณจะต้องอธิบายให้ลูกน้องฟังว่าทำไมการใช้ eval ของคุณถึงดีและไม่ดี
และแน่นอน PHP ของคุณดูเหมือน Perl;)
มีปัญหาสำคัญสองประการเกี่ยวกับ eval () (เป็นสถานการณ์ "ฉีดยาโจมตี"):
1) อาจก่อให้เกิดอันตราย 2) อาจเกิดความผิดพลาด
และสิ่งที่มากกว่าสังคมมากกว่าเทคนิค:
3) มันจะล่อลวงให้ผู้คนใช้มันอย่างไม่เหมาะสมเป็นทางลัดที่อื่น
ในกรณีแรกคุณจะเสี่ยง (เห็นได้ชัดว่าไม่ใช่เมื่อคุณกำลังประเมินสตริงที่ทราบ) จากการใช้รหัสโดยอำเภอใจ ปัจจัยการผลิตของคุณอาจไม่เป็นที่รู้จักหรือคงที่เท่าที่คุณคิด
มีแนวโน้มมากขึ้น (ในกรณีนี้) คุณจะขัดข้องและสตริงของคุณจะจบลงด้วยข้อความแสดงข้อผิดพลาดที่คลุมเครือโดยไม่จำเป็น IMHO รหัสทั้งหมดควรล้มเหลวอย่างเรียบร้อยที่สุดโดยล้มเหลวซึ่งควรทำให้เกิดข้อยกเว้น (เป็นรูปแบบข้อผิดพลาดที่จัดการได้มากที่สุด)
ฉันขอแนะนำว่าในตัวอย่างนี้คุณกำลังเขียนโค้ดโดยบังเอิญมากกว่าการเข้ารหัสพฤติกรรม ใช่คำสั่ง SQL enum (และคุณแน่ใจหรือไม่ว่า enum ของฟิลด์นั้น - คุณเรียกฟิลด์ที่ถูกต้องของตารางที่ถูกต้องของฐานข้อมูลเวอร์ชันที่ถูกต้องหรือไม่มันตอบจริงหรือไม่) ดูเหมือนไวยากรณ์การประกาศอาร์เรย์ใน PHP แต่ฉันขอแนะนำสิ่งที่คุณต้องการทำจริงๆไม่ใช่หาเส้นทางที่สั้นที่สุดจากอินพุตไปยังเอาต์พุต แต่จะจัดการกับงานที่ระบุ:
- ระบุว่าคุณมี enum
- แยกรายชื่อด้านใน
- แกะค่ารายการ
ซึ่งเป็นสิ่งที่ตัวเลือกของคุณทำ แต่ฉันจะสรุป if's และความคิดเห็นรอบ ๆ เพื่อความชัดเจนและความปลอดภัย (เช่นหากการแข่งขันครั้งแรกไม่ตรงกันให้ทิ้งข้อยกเว้นหรือตั้งค่าผลลัพธ์เป็นโมฆะ)
ยังคงมีปัญหาที่เป็นไปได้บางประการเกี่ยวกับเครื่องหมายจุลภาคหรือเครื่องหมายคำพูดที่ใช้ Escape และคุณควรคลายข้อมูลจากนั้นจึงไม่อ้างถึง แต่อย่างน้อยก็ถือว่าข้อมูลเป็นข้อมูลแทนที่จะเป็นรหัส
ด้วย preg_version ผลลัพธ์ที่แย่ที่สุดของคุณน่าจะเป็น $ result = null โดยรุ่น eval จะไม่ทราบเวอร์ชันที่แย่ที่สุด แต่อย่างน้อยก็เกิดข้อขัดข้อง
$result = array(); preg_replace_callback('#^enum\s*\(\s*\'|\'\s*\)\s*$#', function($m) use($result) { $result[] = $m[1]; }, $type);