fivestringsurf Posted July 8, 2013 Share Posted July 8, 2013 I've been working on my own templating feature in which a page of static html is replaced by php variables when they exist. When $ (dollar sign) exists on the static page before the templating magic it is getting omitted when i replace things using preg_replace() for the output. This simple example illustrates this: $price = '$10.99'; $template = 'Your cost: $price'; $output = preg_replace('/\$price/', $price, $template); echo $output; //Your cost: .99 notice the "$" is now missing from output. Anyone know how to solve this problem and preserve dollar signs in an elegant way. I know I can do something like $price = str_replace('$', '\$', $price); but that seems ugly and simply another string function that isn't necessary. (I'm already using a lot of resources to make the templating feature work) Note: I'm using php ver. 5.2 I thought maybe preg_replace_callback() might work but it doesn't seem to be supported Quote Link to comment Share on other sites More sharing options...
Solution requinix Posted July 8, 2013 Solution Share Posted July 8, 2013 (edited) Since you're not actually using regular expressions, str_replace() or strtr (with an array) is better. Anyway, the problem is preg_replace() thinks the "$10" in the replacement string is supposed to be a back-reference to the tenth captured substring. Since there isn't one it uses an empty string. $price = addcslashes('$10.99', '$\\');[edit] preg_replace_callback() should be supported but you'd have to use create_function (if you wanted the function inline), which is a really ugly and bug-prone way of doing it - an actual function somewhere would be better. [edit 2] If you're replacing variables, consider doing a preg_replace() or preg_replace_callback() that simply looks for all things that look like variables, checks if the matched variable exists in some master list (you shouldn't just allow any variable at all), and if so replace with the variable's value. Something like function replaceVariables($string, array $variables) { return preg_replace( '/(?<=\$)[a-z_][a-z0-9_]*/ei', 'isset($variables["$0"]) ? $variables["$0"] : "\$$0"', // check that escaping there, might not work $string ); }(which uses /e, yes, but that's not deprecated until 5.5 and using it is easier than preg_replace_callback() with create_function()). If you really wanted to allow for all variables, which I'll say again is a bad idea that you should seriously reconsider, then you can just pass $GLOBALS: $out = replaceVariables($in, $GLOBALS); Edited July 8, 2013 by requinix Quote Link to comment Share on other sites More sharing options...
fivestringsurf Posted July 8, 2013 Author Share Posted July 8, 2013 first off, thanks for taking the time to provide an explanation! your explanation about "back-reference to the tenth captured substring"... perfect. forgot about that - duh. and you're exactly right about using str_replace(). Not only did str_replace() solve my debacle, it should be way faster too. win/win for my application. Thanks again! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.