2013-03-17 4 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)); 

Однако, если вы не хотите использовать eval вообще, вы, вероятно, в конечном итоге напишите 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); 

И с условиями размещения вы можете добавить предпочтительные константы в свою переменную.

Смежные вопросы