2013-03-17 2 views
1

제가 사용하는 PHP 소프트웨어를 수정하려고하는데 사용자가 E_ALL & ~E_NOTICE과 같은 사용자 지정 오류보고 수준을 입력 할 수 있도록하고 싶습니다.문자열에 error_reporting을 사용 하시겠습니까?

문제는 지정된 값이 문자열로 저장되므로 error_reporting() 함수에서 참조 할 수 없다는 것입니다.

어쨌든 문자열을 error_reporting() 함수에 필요한 값으로 변환 할 수 있습니까? 이미 constant() 함수를 시도했지만 상수를 찾을 수 없다고합니다.

리암

+3

왜 그렇게하고 싶습니까? – zerkms

+0

그건 설명이 아니야.끔찍한 방식으로 무언가를하고있는 가능성이 있습니다 – zerkms

+3

@LiamW - 나는 zerkms에 동의합니다. 그것은 정말로 * 기묘한 일입니다. 나는 그것이 합리적 일 것 인 어떤 유스 케이스라도 상상할 수 없다. 오류를 표시하는 유일한 이유는 사이트에서 작업하는 개발자를 돕는 것입니다. 따라서 일반적으로 dev 시스템에서는 모든 오류를 표시하고 라이브 시스템에서는 모두 숨길 수 있습니다. 실제 시스템을 디버깅하려면 실제로 오류 로그를 사용해야합니다. 그러나 오류를 볼 수있는 설정이 있어도 코어 PHP 플래그를 변경할 수있는 개방형 기능이 아닌 단일 디버그 모드 여야합니다. 그것의 전면에 "보안 구멍"이 새겨 져있다. – Spudley

답변

2

AFAIK, 왜 constant이 여기서 작동하지 않는 주된 이유는 문자열 'E_ALL & ~E_NOTICE'이 상수가 아니기 때문에 두 개의 상수와 비트 연산자가 있기 때문입니다. 그래서 여기서 할 수있는 일은 eval 함수를 사용하는 것입니다. 그러나 조심해서 조심하십시오.

다른 방법은 문자열에 사용 된 모든 상수를 얻는 것입니다. 이를 위해 정규 표현식을 사용할 수 있습니다

$string = 'E_ALL & ~E_NOTICE'; 
$intval = 0; 
preg_match_all('/[A-Z_]+/',$string, $constants); 
//$constants looks like: array(array('E_ALL', 'E_NOTICE')) 
foreach ($constants[0] as $key => $const) 
{ 
    //either converts them to their value 
    $constants[0][$key] = constant($const); 
    //or replace them in the initial string 
    //you can do this using preg_replace_callback, too of course 
    $string = replace($const, constant($const), $string); 
} 

당신이 그들의 값으로 상수 이름을 교체하려는 경우, 당신은 적어도 eval에 당신이 약간 더 안전한 문자열을 전달하고 있는지 확인 할 수 있습니다

$string = preg_replace('/[^0-9&!|\^]/','',$string);//remove anything that isn't a number or bitwise operator. 
error_reporting(eval($string)); 

그러나 을 전혀 사용하지 않으려면을 함수로 사용하여 switch을 작성해야합니다.

//Get the constants 
preg_match_all('/[A-Z_]/',$string,$constants); 
//Get the bitwise operators 
preg_match_all('[&|~^\s]', $string, $bitOps); 

//eg: 
$string= 'E_ALL& ~E_NOTICE ^FOOBAR'; 
//~~> 
$constants = array(array ('E_ALL', 'E_NOTICE', 'FOOBAR')); 
$bitops = array(array(' & ~', ' ^'));//pay close attention to the spaces! 

결론/내 의견 :
왜이 모든 통과 그것은 당신이 그것에게 기회를주고 싶다면, 당신을 위해 비트를하고 기분이 뭔가 아니다? 느리고 비싸고 안전하지 않습니다. 더 안전하고 간단하며 쉬운 솔루션 IMHO는 문자열 대신 int 값을 저장하는 이됩니다.
고객이 error_reporting 레벨을 선택하도록 (왜 볼 수 없나요?), select을 생성하고 미리 정의 된 옵션을 제공하십시오.

완전히 제어하려면 자신의 ini 파일을 사용할 수 있지만 솔직히 말하면 목표는 E_STRICT | E_ALL에서 실행되는 방식으로 코드를 작성하는 것입니다. 그렇다면 변경하려는 인센티브가 많지 않습니다. error_reporting
클라이언트가 자신의 코드를 실행하도록 허용하고 경고 또는 오류가 발생하는 경우 은 , 그러나 그들을 고쳐라!

+0

좋은 해결책 +1! – HamZa

+0

아주 좋은 해결책입니다. 스크립트는 vBulletin이며, 어쨌든 eval()을 너무 많이 사용합니다. 또한 이것은 백엔드 옵션이 될 것입니다. –

-1

당신은 배열에 의해 간단하게 수행 할 수 있습니다

 
     $string = "E_ALL"; 
     $errorLevel = array("E_ALL"  => E_ALL, 
          "E_NOTICE" => E_NOTICE, 
          "E_ERROR" => E_ERROR, 
          "E_WARNING" => E_WARNING, 
          "E_PARSE" => E_PARSE); 
     error_reporting($errorLevel[$string]); 
+2

그리고'E_ALL & ~ E_NOTICE' 입력을 어떻게 처리할까요? – zerkms

0

내가 분할 부분에 대해 알고하지 않습니다하지만이 같은 것을 할 수 있다고 생각 :

$level = NULL; 

// Modifications 
$level = E_ALL; 
$level &= ~E_NOTICE; 

error_reporting($level); 

조건을 입력하면 원하는 상수를 변수에 추가 할 수 있습니다.

관련 문제