My standard answer to this question whenever it crops up:
Don't use eval (especially as you're stating that this is user input) or reinvent the wheel by writing your own formula parser.
Take a look at the evalMath class on PHPClasses. It should do everything that you've listed here.
EDIT
re: Unfortunately evalMath does not handle things like (x > 5)
change lines 177-179 to
$ops = array('+', '-', '*', '/', '^', '_', '>', '<', '=');
$ops_r = array('+'=>0,'-'=>0,'*'=>0,'/'=>0,'^'=>0, '>' => 0, '<' => 0, '=' => 0); // right-associative operator?
$ops_p = array('+'=>0,'-'=>0,'*'=>1,'/'=>1,'_'=>1,'^'=>2, '>' => 0, '<' => 0, '=' => 0); // operator precedence
change line 184 to
if (preg_match("/[^ws+*^/().,-<>=]/", $expr, $matches)) { // make sure the characters are all good
add
case '>':
$stack->push($op1 > $op2); break;
case '<':
$stack->push($op1 < $op2); break;
case '=':
$stack->push($op1 == $op2); break;
after line 321
and evalMath will now handle (x > 5), (x < 5) or (x = 5)
// instantiate a new EvalMath
$m = new EvalMath;
$m->suppress_errors = true;
// set the value of x
$m->evaluate('x = 3');
var_dump($m->evaluate('y = (x > 5)'));
Further Edit
Missed line 307 that should be modified to read:
if (in_array($token, array('+', '-', '*', '/', '^', '>', '<', '='))) {