개인적으로 코드가하는 일에 대해 주석을 달지 않기 때문에 코드가 여전히 매우 악하다고 생각합니다. 또한 입력의 유효성을 테스트하지 않아 매우 취약합니다.
또한 eval 사용의 95 % (또는 그 이상)가 적극적으로 위험하기 때문에 다른 경우에 제공 할 수있는 약간의 잠재적 인 시간 절약은 그것을 사용하는 나쁜 관행에 탐닉 할 가치가 없다고 생각합니다. 또한 나중에 미니언에게 eval 사용이 좋은 이유와 나쁜 이유를 나중에 설명해야합니다.
그리고 물론 PHP는 Perl처럼 보입니다.)
eval ()에는 두 가지 주요 문제가 있습니다 ( "주입 공격"시나리오) :
1) 해를 입힐 수 있습니다. 2) 단순히 충돌 할 수 있습니다.
기술보다 더 사회적입니다.
3) 다른 곳에서 지름길로 부적절하게 사용하도록 사람들을 유혹합니다.
첫 번째 경우에는 임의 코드 실행의 위험이 있습니다 (확실히 알려진 문자열을 평가할 때가 아니라). 그러나 귀하의 입력은 귀하가 생각하는 것처럼 알려 지거나 고정되지 않을 수 있습니다.
더 가능성이 높습니다 (이 경우) 당신은 단지 충돌하고 문자열은 불필요하게 모호한 오류 메시지와 함께 종료됩니다. IMHO, 모든 코드는 가능한 한 깔끔하게 실패해야하며 실패하면 예외가 발생해야합니다 (가장 처리하기 쉬운 오류 형식).
이 예에서는 행동으로 코딩하는 것이 아니라 우연으로 코딩하는 것이 좋습니다. 예, SQL enum 문 (그리고 필드의 enum이 확실합니까?-올바른 데이터베이스 버전의 오른쪽 테이블에서 올바른 필드를 호출 했습니까? 실제로 대답 했습니까?)은 PHP에서 배열 선언 구문처럼 보입니다. 그러나 나는 당신이 정말로 원하는 것은 입력에서 출력까지의 최단 경로를 찾는 것이 아니라 지정된 작업을 처리하는 것입니다.
- 열거 형이 있는지 확인
- 내부 목록 추출
- 목록 값 압축 풀기
대략적으로 옵션 하나가 수행하는 작업이지만 명확성과 안전성을 위해 일부 if 및 주석을 래핑합니다 (예 : 첫 번째 일치 항목이 일치하지 않으면 예외를 throw하거나 null 결과를 설정).
이스케이프 된 쉼표 나 따옴표에는 여전히 몇 가지 문제가있을 수 있으며 데이터의 압축을 풀고 따옴표를 제거해야하지만 최소한 데이터를 코드가 아닌 데이터로 취급합니다.
preg_version을 사용하면 최악의 결과는 $ result = null 일 가능성이 높으며 eval 버전에서는 최악의 상황을 알 수 없지만 최소한 충돌은 발생합니다.
$result = array(); preg_replace_callback('#^enum\s*\(\s*\'|\'\s*\)\s*$#', function($m) use($result) { $result[] = $m[1]; }, $type);