1

Here is what I am trying to do:

<?php
    $my_str = "My String";
    $str = "%my_str";

    $str = str_replace("%", "$", $str);

    echo $str;
?>

The above code prints '$my_str' to the screen. But I want it to print 'My String', as in the actual value of the variable $my_str

Anyone know how to do this?

The reason I want this is because I'm in the process of writing my own, very basic, parsing language so I kinda need this to be functional before I can continue.

Travis Collins
  • 3,982
  • 3
  • 31
  • 44
  • Ok I got what I needed, eval("echo $str;"); does the trick. I'm aware of the security risks but this page can only be accessed by the owner, so it should be fine. Thanks for all the help. –  Sep 03 '09 at 21:10

7 Answers7

9
$my_str = 'My String';
$str    = 'my_str';

echo $$str;

This construction is called a variable variable.

Ionuț G. Stan
  • 176,118
  • 18
  • 189
  • 202
  • I'm not sure this is what the user wanted - they seem to want to perform interpolation of the string, as if it were a literal, rather than just getting the value of the variable named in the string. – Adam Wright Sep 03 '09 at 21:07
  • Indeed this is most certainly not what I am after. I'm completely aware of how variable variables work. Thanks for your help though. (Weird how this is voted up and the other answers, which are exactly what I was after, are voted down) –  Sep 03 '09 at 21:15
  • 1
    Honestly, I don't understand what you were after and I don't understand why `eval` was better in this case. Anyway, if `eval` is better for you, I'm fine with that. – Ionuț G. Stan Sep 03 '09 at 21:24
2

eval is not necessary. Just get rid of the % and use $$str

<?php
    $my_str = "My String";
    $str = "%my_str";

    $str = str_replace("%", "", $str);

    echo $$str;
?>
Dooltaz
  • 2,413
  • 1
  • 17
  • 16
  • Thanks for the help but I want the %, as I said, I'm in the process of making a simple parsing language which processes templates. eval works great, but thanks for your help regardless! –  Sep 03 '09 at 21:08
2

You could search and replace the %var patterns using preg_replace and the e modifier, which makes the replacement being evaluated:

<?php
    $my_str = "My String";
    $str = "Foo %my_str bar";

    $str = preg_replace("/%([A-Za-z_]+)/e", "$\\1", $str);

    echo $str;
?>

Here preg_replace will find %my_str, \1 contains my_str and "$\\1" (the backslash needs to be escaped) becomes the value of $my_str.

However, it would maybe be cleaner to store your replacement strings in an associative array:

<?php
    $replacements = array(
        "my_str" => "My String",
    );
    $str = "Foo %my_str bar";

    $str = preg_replace("/%([A-Za-z_]+)/e", '$replacements["\\1"]', $str);

    echo $str;
?>
1

Try:

echo $$str;
krdluzni
  • 799
  • 2
  • 9
  • 10
0

PHP automatically parses and expands variables within double-quoted strings:

<?php
    $my_str = "My String";
    $str = "{$my_str}";

    echo $str;
?>

Outputs:

My String
shufler
  • 926
  • 7
  • 23
0

How about using a regex with the e modifier

$str = preg_replace("/%([a-zA-Z0-9_]+)/e", '$\1', $str);

(This is untested, but should work)

MiffTheFox
  • 21,302
  • 14
  • 69
  • 94
-1

The behaviour you see is not surprising - expansion of variables ("interpolation") is performed on only string literals, rather than variables. If it wasn't, then it would be a large security hole (any instance of a string with $ in it that your code used would suddenly be revealing variables).

You can try and fix this using eval, as in

eval ("\$str = \"" . str_replace("%", "\$", $str) . "\"");

but this pretty dangerous - if your string is from the user, then can make $str something like

"; system("rm -rf /"); $x = "

and suddenly, you're in trouble. The best solution, I believe, will be to parse out variables using your favourite methods (stripos and substring, or something more), then replace each one by hand.

Adam Wright
  • 48,938
  • 12
  • 131
  • 152
  • Actually that code gives me errors. eval("\$str = \"" . str_replace("%", "$", $str) . "\";"); That works though, cheers for the help. –  Sep 03 '09 at 21:12