Trick of course is to avoid any risk of arbitrary code in the eval (well, there's also the problems it causes for static analysis - variables that appear to be undeclared and so on). If it is that well-controlled (i.e., the PHP-encoded rules are generated by a correct PHP script and only those rules are eval()ed), then eval would seem the most straightforward way of saying what's going on. Then serialise the rule specification for later sessions by saving the code.
An alternative would be a stream wrapper that makes "get a PHP-encoded rule from the database" look like "read a file" from a suitable URL, then include() could be used.
I suspect the most convenient way of getting the functionality of the code into the program (i.e., what to do with the rule text once it's parsed) would be to use it to an anonymous function with the code as its body; then that can be passed out from the retrieval routine to wherever it's actually going to be used.
In fact, since those anonymous functions are declared on the fly, and depending on what your rules look like, you might be able to do the whole rule-specification thing on the fly as well, and avoid the eval that way. Of course, then you're back to the need to serialising the rule specification for later sesions.
It kind of depends on how elaborate these rules can get; but I can picture, .... ooh, let's say ... serialising a JSON-encoded (possibly nested) array/object to be parsed into a PHP object, then traversing that object using it as a shopping list while pulling component functions from a parts library ("okay, I need a foofilter that matches 42 and a meaningfilter that matches 'life' ... [font=monospace]function foofilter($value) { return function($thingy)use($value) { return $thingy->foo == $value; }; }; ... $foofilter_42 = foofilter(42); ... array_filter($objects, $foofilter_42);[/font]").