Reputation: 1163
I am making a modification for a PHP software I use and I am wanting to allow users to enter a custom error reporting level, such as E_ALL & ~E_NOTICE
.
The issue is that the value they specifiy is saved as a string - and therefore I cannot reference it in the error_reporting()
function.
Is there anyway I could convert the string into the value needed by the error_reporting()
function? I have already tried the constant()
function, however it says that the constant cannot be found.
Liam
Upvotes: 2
Views: 987
Reputation: 76397
AFAIK, the main reason why constant
isn't working for you here is because the string 'E_ALL & ~E_NOTICE'
isn't a constant, but it's two constants and some bitwise operators. So what you could do here is use the eval
function. However... be careful, be very careful.
An other way of going at it is getting all constants used in the string. You could use a regular expression for this:
$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);
}
If you choose to replace the constant names with their values, you can at least make sure you're passing a slightly more secure string to eval
:
$string = preg_replace('/[^0-9&!|\^]/','',$string);//remove anything that isn't a number or bitwise operator.
error_reporting(eval($string));
However, if you don't want to use eval at all, you'll probably end up writing a switch
in a function somewhere. That's not something I feel like doing for you, bit if you want to give it a shot:
//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!
Conclusion/My opinion:
Why go through all this? It's slow, it's expensive, and insecure. A safer, simpler and easier solution IMHO would be to store the int value, instead of a string.
You want your clients to choose the error_reporting
level (I can't see why...), why not create a select
and give them a number of predefined options.
If you want to give them full control, allow them to use their own ini-file, but frankly: your goal should be to write your code in such a way that it runs under E_STRICT | E_ALL
. If you do, there's not a lot of incentive to change error_reporting
...
If you're allowing your clients to run their own code, and it's raising warnings or errors, please point out to them that they shouldn't suppress, but FIX them!
Upvotes: 3
Reputation: 2382
I don't know about the splitting part but I think you're able to do something like this:
$level = NULL;
// Modifications
$level = E_ALL;
$level &= ~E_NOTICE;
error_reporting($level);
And with putting conditions you can add preferred constants to your variable.
Upvotes: 0
Reputation: 4383
you can do it simply by array:
$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]);
Upvotes: -1