3

NOTE: Eval is used here in total knowledge, the string parsed is entered by an administrator only, and the purpose is to store instructions in database, without restrictions to the instructions. If you have a good alternative, it is always appreciated, but don't just say "eval is bad".

I have a String in PHP, for example

$myString = "(35*$var1*64)/$var2";

I want to eval() this string, but before, I want to modify all the variables in the string like this:

$var2 -> $_POST['var2']

There may or may not be a blank space after the variable in $myString .

When I eval $myString, PHP throws an error "Undefined variable $var1". PHP read the string and parse the variables, so I guess there should be a way to parse all the variables in the string.

The output should be:

$myStringParsed = "(35*$_POST['var1']*64)/$_POST['var2']";

or an equivalent.

2
  • 1
    Don't use " for string, as parser adds variables to string and it does not goes to eval tring. Also where is your eval code? Commented May 31, 2016 at 9:31
  • $myStringParsed = "(35*$_POST[$var1]*64)/$_POST[$var2]"; should be $myStringParsed = "(35*{$_POST[$var1]}*64)/{$_POST[$var2]}"; So, add the { } instances. Commented May 31, 2016 at 10:06

3 Answers 3

1

Not maybe the best solution, but you can preprocess $_POST variable and generate $variablesString like this:

$variablesString = '';
foreach($_POST as $key => $val) {
    $variablesString .= '$' . $key . ' = ' . $val . ';' . PHP_EOL;
}

eval($variablesString . PHP_EOL . $myString)

For string support you can check if $val is string, and if yes - wrap it with quotes.

Second way

$myString = 'return (35 * $var1 * 64) / $var2;';
$re = "/\\$(\\w*)/im";

preg_match_all($re, $myString, $matches);

foreach($matches[1] as $match) {
    $search = '$' . $match;
    $replace = '$_POST[\'' . $match . '\']';
    $myString = str_replace($search, $replace, $myString);
}
echo eval($myString);

You can check it here

Sign up to request clarification or add additional context in comments.

7 Comments

I can send anything in POST. like 0; unlink('/')
Yes, you can. But Nathan noticed: Eval is used here in total knowledge, the string parsed is entered by an administrator only
It is still worth to notice it, since not only the OP will read this thread. You know we have space tech like search engines to find stuff on a mysterious network called internet.
This solution is what I'm using right now. The problem is that I have to create the variables for EACH element in $_POST. Also, the question was focused on the parsing of the string. This solution works in my case, but there may be other cases where it isn't efficient. If no one provides a parsing solution, I'll accept this one.
@IgorRynkovoy Yes, this is exactly what I want. It also works when the * touches the $var2. I don't know regex yet, will that work for *, +, -, / ? Tried on your example and it seemed to. Anyway, this is the solution. Thanks.
|
0

Assuming you mean....

$myString = '(35*$var1*64)/$var2';

The a more robust solution (consider $myvar10) than that suggested by ASGM is:

$replace=array(
   '/\b\$var1\b/'=>$_POST['var1'], 
   '/\b\$var2\b/'=>$_POST['var2'],
   ...
);
$interpolated=preg_replace(array_keys($replace)
    , $replace, $myString);

Note that I would recommend that you interpolate the string with literals rather than substituting one place holder for another. In addition to eliminating unnecessary processing, it also means you can check the content of the resulting string to ensure it only contains digits and operators (and a restricted number of functions if appropriate).

1 Comment

It seems the question wasn't clear. I can't know beforehand if the name of the variables will be $var1 or $myVar or such. I want to parse the string for any expression that would be a variable.
0

You are using wrong string enclosing quotes. Use '(35*$var1*64)/$var2':

//$var1 = $_POST['var1'];
//$var2 = $_POST['var2'];

$var1 = '10';
$var2 = '20';

$myString = 'return (35 * $var1 * 64) / $var2;';

echo eval($myString);
//1120

Working example of eval


If you want to take any variable from POST, than you can use extract() to get array keys as variables with associated values:

<?php
// Change it to real $_POST
$POST = [
    'var1' => '10',
    'var2' => '20',
];

extract($POST, EXTR_SKIP);

$myString = 'return (35 * $var1 * 64) / $var2;';

echo eval($myString);

4 Comments

Thanks for your answer. No, the variables $var1 and $var2 are NOT defined. I just pointed the fact that they are parsed by PHP. I want to replace these expressions.
@Nathan You can't work with undefined variables. That's why I have commented how they should be defined using $_POST. Also if $var2 is not defined than $_POST[$var2] makes no sense.
I'm sorry, you are right. My question was false. The fact is that $var2 is not defined but $_POST['var2'] is. I forgot to take out the $. Edited question.
@Nathan Check updated answer on how to extract POST to variables.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.