Asked  7 Months ago    Answers:  5   Viewed   186 times

In all the years I have been developing in php, I've always heard that using eval() is evil.

Considering the following code, wouldn't it make sense to use the second (and more elegant) option? If not, why?

// $type is the result of an SQL statement
// e.g. SHOW COLUMNS FROM a_table LIKE 'a_column';
// hence you can be pretty sure about the consistency
// of your string
$type = "enum('a','b','c')";

// possibility one
$type_1 = preg_replace('#^enums*(s*'|'s*)s*$#', '', $type);
$result = preg_split('#'s*,s*'#', $type_1);

// possibility two
eval('$result = '.preg_replace('#^enum#','array', $type).';');

 Answers

57

I would be cautious in calling eval() pure evil. Dynamic evaluation is a powerful tool and can sometimes be a life saver. With eval() one can work around shortcomings of PHP (see below).

The main problems with eval() are:

  • Potential unsafe input. Passing an untrusted parameter is a way to fail. It is often not a trivial task to make sure that a parameter (or part of it) is fully trusted.
  • Trickiness. Using eval() makes code clever, therefore more difficult to follow. To quote Brian Kernighan "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it"

The main problem with actual use of eval() is only one:

  • Inexperienced developers who use it without enough consideration.

As a rule of thumb I tend to follow this:

  1. Sometimes eval() is the only/the right solution.
  2. For most cases one should try something else.
  3. If unsure, goto 2.
  4. Else, be very, very careful.
Wednesday, March 31, 2021
 
Shreejibawa
answered 7 Months ago
26

Eric Lippert sums eval up over three blog posts. It's a very interesting read.

As far as I'm aware, the following are some of the only reasons eval is used.

For example, when you are building up complex mathematical expressions based on user input, or when you are serializing object state to a string so that it can be stored or transmitted, and reconstituted later.

Wednesday, March 31, 2021
 
kinske
answered 7 Months ago
16

Well, executing arbitrary strings as code has the caveat that you're executing arbitrary code whichever way you do it. There's no better alternative to eval that would let you execute PHP code without… executing PHP code.

The sane way to go here is to define a DSL which gives your users a way to write certain limited expressions which are not PHP code, which you will parse and evaluate with specific limited capabilities.

A good library which does that is Symfony's ExpressionLanguage component. Beyond that you'd go into the domain of language parsers.

Friday, May 28, 2021
 
Axalix
answered 5 Months ago
20

I'd like to take a moment to address the premise of your question - that eval() is "evil". The word "evil", as used by programming language people, usually means "dangerous", or more precisely "able to cause lots of harm with a simple-looking command". So, when is it OK to use something dangerous? When you know what the danger is, and when you're taking the appropriate precautions.

To the point, let's look at the dangers in the use of eval(). There are probably many small hidden dangers just like everything else, but the two big risks - the reason why eval() is considered evil - are performance and code injection.

  • Performance - eval() runs the interpreter/compiler. If your code is compiled, then this is a big hit, because you need to call a possibly-heavy compiler in the middle of run-time. However, JavaScript is still mostly an interpreted language, which means that calling eval() is not a big performance hit in the general case (but see my specific remarks below).
  • Code injection - eval() potentially runs a string of code under elevated privileges. For example, a program running as administrator/root would never want to eval() user input, because that input could potentially be "rm -rf /etc/important-file" or worse. Again, JavaScript in a browser doesn't have that problem, because the program is running in the user's own account anyway. Server-side JavaScript could have that problem.

On to your specific case. From what I understand, you're generating the strings yourself, so assuming you're careful not to allow a string like "rm -rf something-important" to be generated, there's no code injection risk (but please remember, it's very very hard to ensure this in the general case). Also, if you're running in the browser then code injection is a pretty minor risk, I believe.

As for performance, you'll have to weight that against ease of coding. It is my opinion that if you're parsing the formula, you might as well compute the result during the parse rather than run another parser (the one inside eval()). But it may be easier to code using eval(), and the performance hit will probably be unnoticeable. It looks like eval() in this case is no more evil than any other function that could possibly save you some time.

Tuesday, June 1, 2021
 
turik
answered 5 Months ago
52

you can have a variable variable/function, but cannot have variable method chains. you can however create a method chain using variable variables/functions.

Check this page of the php documentation: http://php.net/manual/en/language.variables.variable.php

it shows the usage of using strings as object or method names. using eval may lead to security vulnerabilities depending on the source of your data.

$var1 = 'model_db';
$var2 = 'get_results';

$this->$var1->$var2();
Thursday, August 26, 2021
 
BrunoRamalho
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :