Jump to content

The eval() Language Construct


iwato

Recommended Posts

REQUEST: Please provide a human-friendly translation of what is occurring in the expressions of the two eval() constructs below.NOTE: The two sets of code are completely unrelated, but the use of the eval() statements appear to be similar. Both were obtained from the following webpage.

<?php	$string = 'cup';	$name = 'coffee';	$str = 'This is a $string with my $name in it.';	echo $str. "\n";	eval("\$str = \"$str\";");	echo $str. "\n";?>

<?php	$array = array('a','b','c');	$a = 'bah'; $b = 'bleh2'; $c = 'bluh3';	echo $a . '<br />';	echo $b . '<br />';	echo $c . '<br /><br />';	foreach($array as $element) {		print("$element<br />");		eval("\$$element = \"$element\";");	};	print("vars aft: $a, $b, $c.");?>

Roddy

Link to comment
Share on other sites

Euuu.... what an ugly examples. Then again, eval() is evil, so that is to be expected.First example:The first and second lines are clear. The third creates a string that contains the exact text you see, because it uses single quotes instead of double quotes. This same variable is then echoed for the sake of showing you what it contains, and a new line is added for readability's sake.And here's where it gets ugly... in double quotes, variable interpolation is enabled. To escape actual double quotes that occur in the string, a "\" is placed before each quote, and "\" is also placed before one of the "$" to write out a literal "$" instead of using the value of the $str variable. It's not placed at the "$" between the quotes, so you get the actual value of the $str variable there. The resulting string is therefore:

$str = "This is a $string with my $name in it.";

This string is then evaluated as PHP code, and since it's a string in double quotes, variable interpolation is enabled, and the result is stored in the $str variable. Stuff in eval() is intertwined with the PHP code that called eval(), so the $str variable within the eval() is actually the same $str that was printed right before eval(). The following echo therefore prints the new value that was set during the eval().Second example:Similar premise, but with arrays. I'm not going to even try to explain it in more detail, as it makes me want to puke.

Link to comment
Share on other sites

Similar premise, but with arrays. I'm not going to even try to explain it in more detail, as it makes me want to puke.
OK. So, let's return to the first example that is clearly less troublesome.Firstly, I understand that the expression contained within the eval() construct must be valid PHP code. What I understand from this is the following:
  • A variable name that appears in a string enclosed in double-quotation marks yields the value of that variable.
  • Placing a backslash in front of a character escapes the special meaning of that character and causes it to appear as a normal character.

So, if I have understood correctly, the expression "\$str = \"$str\";" is being interpreted by PHP as $str = "$str". In other words, the value of $str is being reassigned to itself as a string in double quotation marks. This is not all that difficult.If this is true, however, then why must the string be placed in double-quotation marks a second time? Why not single quotes? Or, no quotation marks at all?Is it because the escapes characters would not be properly read?Roddy

Link to comment
Share on other sites

OK. So, let's return to the first example that is clearly less troublesome.Firstly, I understand that the expression contained within the eval() construct must be valid PHP code. What I understand from this is the following:
  • A variable name that appears in a string enclosed in double-quotation marks yields the value of that variable.
  • Placing a backslash in front of a character escapes the special meaning of that character and causes it to appear as a normal character.

So, if I have understood correctly, the expression "\$str = \"$str\";" is being interpreted by PHP as $str = "$str". In other words, the value of $str is being reassigned to itself as a string in double quotation marks. This is not all that difficult.If this is true, however, then why must the string be placed in double-quotation marks a second time? Why not single quotes? Or, no quotation marks at all?Is it because the escapes characters would not be properly read?Roddy

Leaving eval() aside, a string with single quotation marks will not parse variables. In a string surrounded with double-quotes, variables will yield the value they contain. You need delimiters around a string so that PHP can recognize that it's a string and not some command or something else.
$v = 1;echo "Number $v"; // Prints "Number 1"echo 'Number $v'; // Prints "Number $v"

Link to comment
Share on other sites

Leaving eval() aside, a string with single quotation marks will not parse variables. In a string surrounded with double-quotes, variables will yield the value they contain. You need delimiters around a string so that PHP can recognize that it's a string and not some command or something else.
Yes, I understand that double-quotes are required to obtain the values. Actually, I knew this even before boen_robot confirmed the notion for me. What I do not understand is why they should be needed again. After all, the statement $str = "$str"; clearly reassigns the values of $string and $name -- namely, 'cup' and 'coffee' -- as the new values of $str.RoddyCoke can be just as addictive as coffee, plus it will make you fat.
Link to comment
Share on other sites

Yes, I understand that double-quotes are required to obtain the values. Actually, I knew this even before boen_robot confirmed the notion for me. What I do not understand is why they should be needed again. After all, the statement $str = "$str"; clearly reassigns the values of $string and $name -- namely, 'cup' and 'coffee' -- as the new values of $str.RoddyCoke can be just as addictive as coffee, plus it will make you fat.
eval() parses a string as if it were PHP code.When typing this:
 eval("\$str = \"$str\";");

It's actually evaluating this:

$str = "This is a $string with my $name in it.";

The value of $str is what's being evaluated, not a pointer to its value.

Link to comment
Share on other sites

The code in the example is useless... which is one more reason why it's so ugly. In the particular example, you might as well have written

$str = "This is a $string with my $name in it.";

from the third line, instead of having that in an eval().

Link to comment
Share on other sites

The value of $str is what's being evaluated, not a pointer to its value.
Ingolme, I still do not understand!When I look at the following code
$str = "This is a $string with my $name in it.";

I understand that the new value of $str is a string whose value is 'This is a cup with my coffee in it." So, I think still again, "Why are the double-quotes needed, if any quotes at all."Roddy

Link to comment
Share on other sites

Ingolme, I still do not understand!When I look at the following code
$str = "This is a $string with my $name in it.";

I understand that the new value of $str is a string whose value is 'This is a cup with my coffee in it." So, I think still again, "Why are the double-quotes needed, if any quotes at all."Roddy

The double-quotes are needed because this is a syntax error:
$str = This is a $string with my $name in it.;

Link to comment
Share on other sites

The code in the example is useless... which is one more reason why it's so ugly. In the particular example, you might as well have written
$str = "This is a $string with my $name in it.";

from the third line, instead of having that in an eval().

Boen_robot, you are shirking the question! This is not like you.In any case, I do not care about the utility of the code, only my ability to understand what makes it work. The utility will come later!Roddy
Link to comment
Share on other sites

Boen_robot, you are shirking the question! This is not like you.In any case, I do not care about the utility of the code, only my ability to understand what makes it work. The utility will come later!Roddy
Sorry... I just hate eval(). There's always a way to do things without it, almost always that would be a better way too, and there's no good reason to use eval() in any case.... especially not in PHP (for JavaScript, I can understand its usage as a JSON parser alternative).
Link to comment
Share on other sites

The double-quotes are needed because this is a syntax error:
$str = This is a $string with my $name in it.;

Yes, Ingolme, but that is not what is being read, rather the following:
$str = "This is a $string with my $name in it.;"

And surely, after it is read, the value of $str is either 'This is a cup with my coffee in it'? or "This is a cup with my coffee in it"?Roddy

Link to comment
Share on other sites

Yes, Ingolme, but that is not what is being read, rather the following:
$str = "This is a $string with my $name in it.;"

And surely, after it is read, the value of $str is either 'This is a cup with my coffee in it'? or "This is a cup with my coffee in it"?Roddy

The string you pass to eval() is first parsed by the main PHP parser before being reparsed in the eval() statement.eval("\$str = $str");is just the same aseval('$str = This is a $string with my $name in it.')which is incorrect PHP.
Link to comment
Share on other sites

Yes, Ingolme, but that is not what is being read, rather the following:
$str = "This is a $string with my $name in it.;"

And surely, after it is read, the value of $str is either 'This is a cup with my coffee in it'? or "This is a cup with my coffee in it"?Roddy

After the eval(), the variable $str has the value
This is a cup with my coffee in it

Single or double quotes are only a PHP notation. Internally, neither quotes are used. Internally, there's just a string value. Depending on the quote notation in your PHP code, the value is computed in different ways.

Link to comment
Share on other sites

OK, you guys. This is it.Our discussion has encouraged me to dig deeper. Here is the error message that I get when I write the string with single quotes:

Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /Applications/MAMP/htdocs/php-practice/function_reference/other_basic_extensions/miscellaneous/miscellaneous functions/eval/eval.php(59) : eval()'d code on line 1
And this is what I get, when I run it with no quotation marks at all.
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /Applications/MAMP/htdocs/php-practice/function_reference/other_basic_extensions/miscellaneous/miscellaneous functions/eval/eval.php on line 59
Please interpret.Roddy
Link to comment
Share on other sites

OK, you guys. This is it.Our discussion has encouraged me to dig deeper. Here is the error message that I get when I write the string with single quotes:And this is what I get, when I run it with no quotation marks at all.Please interpret.Roddy
I can't tell what's wrong without seeing exactly what the code looks like.The first error message is only an error after the string has been evaluated. The second error is being sent from the main PHP parser, which means that your code has a real error in it.
Link to comment
Share on other sites

What exactly do you have?

eval("\$str = '$str';");

Should work, but will not have any effect on the value of $str.

Link to comment
Share on other sites

I can't tell what's wrong without seeing exactly what the code looks like.The first error message is only an error after the string has been evaluated. The second error is being sent from the main PHP parser, which means that your code has a real error in it.
The following two lines of code correspond to the two previously displayed errors messages, respectively1) eval('\$str = \"$str\";');2) eval(\$str = \"$str\":);Now, I interpret the first error to have meant that single quotation marks do not work because \ cannot be understood.I interpret the second error to mean that \ was a syntactical error of some sort.Roddy
Link to comment
Share on other sites

eval("\$str = '$str';");

Should work, but will not have any effect on the value of $str.

Yes, this is correct. It works with no effect.Roddy
Link to comment
Share on other sites

I think the first error steams from the fact that

'\$str = \"$str\";'

is evaluated to

\$str = \"$str\";

which is invalid PHP code.The second error is because strings need to be surrounded with single or double quotes, not start with "\", as is in

eval(\$str = \"$str\";);

Link to comment
Share on other sites

I think the first error steams from the fact that
'\$str = \"$str\";'

is evaluated to

\$str = \"$str\";

which is invalid PHP code.

If this were true, then why would
"\$str = \"$str\";"

not also be evaluated as

\$str = \"$str\";

Additional research yields the following:Single quotedThe simplest way to specify a string is to enclose it in single quotes (the character ').To specify a literal single quote, escape it with a backslash (\). To specify a literal backslash before a single quote, or at the end of the string, double it (\\). Note that attempting to escape any other character will print the backslash too.Note: Unlike the double-quoted and heredoc syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings. Double quotedIf the string is enclosed in double-quotes ("), PHP will interpret more escape sequences for special characters:Escaped characters Sequence Meaning\n linefeed (LF or 0x0A (10) in ASCII)\r carriage return (CR or 0x0D (13) in ASCII)\t horizontal tab (HT or 0x09 (9) in ASCII)\v vertical tab (VT or 0x0B (11) in ASCII) (since PHP 5.2.5)\f form feed (FF or 0x0C (12) in ASCII) (since PHP 5.2.5)\\ backslash\$ dollar sign\" double-quote\[0-7]{1,3} the sequence of characters matching the regular expression is a character in octal notation\x[0-9A-Fa-f]{1,2} the sequence of characters matching the regular expression is a character in hexadecimal notationAs in single quoted strings, escaping any other character will result in the backslash being printed too. Before PHP 5.1.1, the backslash in \{$var} had not been printed.Source: http://th2.php.net/manual/en/language.types.string.phpIt is because of you guys that I knew where to look.Many thanks!Roddy

Link to comment
Share on other sites

You can see that among the additional escape sequences in double quotes, you have

\$ dollar sign\" double-quote
So, if we have to analyze
"\$str = \"$str\";"

character by character, we see that there is a literal '$', 'str = ', a literal double quote, non escaped dollar sign that makes the following alphanumberic characters the name of a variable to get the value of, 'str' is the longest alphanumeric word we get before reaching a backslash, so we get the $str variable's value (whih was earlier set to 'This is a $string with my $name in it.'), another literal double quote, ';'. Therefore, this string is evaluated to

$str = "This is a $string with my $name in it.";

Link to comment
Share on other sites

Therefore, this string is evaluated to
$str = "This is a $string with my $name in it.";

Yes, this is exactly my point.The reason that the double quotes are necessaryis to evaluate the escaped characters properly. Hooray! I have properly understood.Roddy
Link to comment
Share on other sites

Hooray! I have properly understood.
So, that everyone else is clear.The following code creates the following class definition using the eval() construct. class SomeClass { var $value = "somevalue"; function show() { echo get_class($this); } } The argument used in the eval( ) construct includes no escape characters and uses single quotation marks to denote the string parameter required by the eval() construct. After the eval() construct is called one can create an instance of SomeClass and call the class's properties and methods just as if the class had been inserted directly into the PHP code.$class = 'class SomeClass { var $value = "somevalue"; function show() { echo get_class($this);}}';eval($class);This example shows two things:1) the value of the eval( ) construct must be a string.2) the double quotation marks are only necessary when certain values within the string must be escaped -- for example, the PHP variable marker $ and the escape character \ -- none of which are necessary for the above code to work.Once again, many thanks to both boen_robot and ingolme for participating in the discussion.The beast has been tamed.Roddy
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...