For reasons I'd rather not get into right now, I have a string like so:
<div>$title</div>
that gets stored in a database using mysql_real_escape_string.
During normal script execution, that string gets parsed and stored in a variable $string and then gets sent to a function($string).
In this function, I am trying to:
function test($string){
$title = 'please print';
echo $string;
}
//I want the outcome to be <div>please print</div>
This seems like the silliest thing, but for the life of me, I cannot get it to "interpret" the variables.
I've also tried,
echo html_entity_decode($string);
echo bin2hex(html_entity_decode($string)); //Just to see what php was actually seeing I thought maybe the $ had a slash on it or something.
I decided to post on here when my mind kept drifting to using EVAL().
This is just pseudocode, of course. What is the best way to approach this?
Your example is a bit abstract. But it seems like you could do pretty much what the template engines do for these case:
function test($string){
$title = 'please print';
$vars = get_defined_vars();
$string = preg_replace('/[$](\w{3,20})/e', '$vars["$1"]', $string);
echo $string;
}
Now actually, /e is pretty much the same as using eval. But at least this only replaces actual variable names. Could be made a bit more sophisticated still.
I don't think there is a way to get that to work. You are trying something like this:
$var = "cute text";
echo 'this is $var';
The single quotes are preventing the interpreter from looking for variables in the string. And it is the same, when you echo a string variable.
The solution will be a simple str_replace.
echo str_replace('$title', $title, $string);
But in this case I really suggest Template variables that are unique in your text.
You just don't do that, a variable is a living thing, it's against its nature to store it like that, flat and dead in a string in the database.
If you want to replace some parts of a string with the content of a variable, use sprintf().
Example
$stringFromTheDb = '<div>%s is not %s</div>';
Then use it with:
$finalString = sprintf($stringFromTheDb, 'this', 'that');
echo $finalString;
will result in:
<div>this is not that</div>
If you know that the variable inside the div is $title, you can str_replace it.
function test($string){
$title = 'please print';
echo str_replace('$title', $title, $string);
}
If you don't know the variables in the string, you can use a regex to get them (I used the regex from the PHP manual).
function test($string){
$title = 'please print';
$vars = '/(?<=\$)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/';
preg_match_all($vars, $string, $replace);
foreach($replace[0] as $r){
$string = str_replace('$'.$r, $$r, $string);
}
echo $string;
}
Related
Is there a built in php function that will return an array (or some sort of list) of all the form elements within a div or within a specific form by either name or id?
My limited experience in javascript tells me that this can probably be occomplished with javascript but i am wondering if it can be done in php. Thanks for your help.
My only other alternative would be to define a variable at the bottom of each form element like:
$allElements = 'name';
$allElements .= ', phone';
$allElements .= ', email';
and so on.
I am wondering if there is a short cut to this method?
You are going to want to parse the HTML.
$HTML = '<div name="phone"></div>';
$string = strstr($HTML, 'name=\"');
$string = strstr($string, '\"');
something like that...
these are your best friends:
stripos()
strrpos()
strripos()
strstr()
strpbrk()
substr()
Don't really know what you exactly mean.
All variables from a sent form are stored in the $_POST global variable. This will show you the list:
if ($_POST) {
echo '<pre>';
echo print_r($_POST);
echo '</pre>';
}
Maybe you need to parse HTML with PHP - see the answer above.
I'm writing a mail class that pulls content stored in a database and loads it into a template before sending it as a HTML e-mail. However, because each e-mail contains PHP variables and dynamic content, I've decided to use delimiters. So instead of the content looking like:
Hello $username, welcome to the site.
It'll look like:
Hello {{username}}, welcome to the site.
So far I'm using these methods:
function load($name,$content)
{
// preps the template for HTML
}
function content($template_id)
{
$template = $this->db->get_where('email_templates',array('id'=>$template_id));
return $template->content;
}
function new_email($email,$name,$user_type)
{
$msg = $this->load($name,$this->content(1));
$this->send($email,'Thanks for your application',$msg,1);
}
The trouble I'm having is how to convert a {{variable}} into a $variable so that it will parse - I don't want it to just be loaded as $username in the e-mail template. Is it just a case of using regular expressions and escaping the string so that it'll parse? Something like:
$content = str_replace("{{","'.$",$template->content);
$content = str_replace("}}",".'",$template->content);
Or is this flawed? Does anybody know what's the best thing to do?
I would not create my own templating system, because there are existing ones out there.
The most popular is probably Smarty, but there is an another one which has the same format as you created, that is mustache.
Update:
The problem with your code is that you're replacing the {{ to a .$ and store that in $content variable, then replacing }} to . and overwrite this replaced $content variable.
A possible working solution could be:
if (preg_match_all("/{{(.*?)}}/", $template, $m)) {
foreach ($m[1] as $i => $varname) {
$template = str_replace($m[0][$i], sprintf('$%s', $varname), $template);
}
}
But then you would also need to eval your code somehow.
So after converting {{variable}} to $variable in your email template, you will use eval to get it replaced by the actual contents of that variable?
Why not just replace {{variable}} with the contents of $variable straight away?
Perhaps have a function that takes the template text and an array of placeholder => "text to replace it with". Then it's as simple as making up the placeholders' exact strings by adding {{ and }} around that array's key and doing str_replace.
foreach ($replacements as $placeholder => $value) {
$placeholder = "{{" . $placeholder . "}}" ;
$text = str_replace($placeholder, $value, $text) ;
}
Couple this with (class) constants for the placeholders and you have a very solid and typo-repelant templating system. It will not be as elegant or easy to use as a full blown templating solution, and it might require extra work from whoever writes code that uses it, but they will not make mistakes during development due to mis-named variables.
If you are going to do it yourself it is probably best to just be explicit with str_replace. If you try to convert the curly bracers to $ you'll then need to eval() which is a potential security hole.
This would be my approach with str_replace - this becomes difficult to maintain as you add more variables but it really doesn't get much simpler either.
$content = str_replace(
array('{{username}}','{{var2}}'),
array($username,$var2),
$template->content
);
use preg_replace_callback , see : http://codepad.org/EvzwTqzJ
<?php
$myTemplateStr = "Hello {{username}} , this is {{subject}} ,and other string {{example}}";
$tagRegex = "|{{(.*?)}}|is";
$result = preg_replace_callback($tagRegex,"myReplaceFunc",$myTemplateStr);
echo $result ;
/* output :
Hello $username , this is $subject ,and other string {{example}}
*/
function myReplaceFunc($matches)
{
$validTags = array('username','subject','name');
$theFull = $matches[0];
$theTag = $matches[1];
if(in_array($theTag,$validTags) == true)
return '$'.$theTag;
return $theFull ;
}
?>
$template = "Hello {{username}} , this is {{subject}} ,and other the answer is on page {{example}}";
$replacements = array(
'username' => 'Jeffrey',
'subject' => 'your final notice',
'page' => 43
);
function bind_to_template($replacements, $template) {
return preg_replace_callback('/{{(.+?)}}/',
function($matches) use ($replacements) {
return $replacements[$matches[1]];
}, $template);
}
echo bind_to_template($replacements, $template);
Credit to https://www.labnol.org/code/19266-php-templates
I would like to know if there is a way to bind PHP function inside a regexp.
Example:
$path_str = '/basket.php?nocache={rand(0,10000)}';
$pattern = ? // something i have no idea
$replacement = ? // something i have no idea
$path = preg_replace($pattern, $replacement, $path_str);
Then :
echo "'$path'";
would produce something like
'/basket.php?nocache=123'
A expression not limited to the 'rand' function would be even more appreciated.
Thanks
You could do the following. Strip out the stuff in between the {} and then run an eval on it and set it to a variable. Then use the new variable. Ex:
$str = "/basket.php?nocache={rand(0,10000)}";
$thing = "rand(0,10000)";
eval("\$test = $thing;");
echo $test;
$thing would be what's in the {} which a simple substr can give you. $test the becomes the value of executing $thing. When you echo test, you get a random number.
Don't, whatever you do, store PHP logic in a string. You'll end up having to use eval(), and if your server doesn't shoot you for it, your colleagues will.
Anywhoo, down to business.
Your case is rather simple, where you need to append a value to the end of a string. Something like this would be sufficient
$stored = '/basket.php?nocache=';
$path = $stored . rand(0,10000);
If, however, you need to place a value somewhere in the middle of a string, or possibly in a variable location, you could have a look at sprintf()
$stored = '/basket.php?nocache=%d&foo=bar';
$path = sprintf($stored, rand(0,10000));
I would not try to store functions in a database. Rather store some kind of field that represents the type of function to use for each particular case.
Then inside your crontab you can do something like:
switch ($function)
{
case 'rand':
$path_str = '/basket.php?nocache='. rand(0,10000);
}
e.t.c
I would like to know if it's possible to execute the php code in a string. I mean if I have:
$string = If i say <?php echo 'lala';?> I wanna get "<?php echo 'dada'; ?>";
Does anybody knows how?
[EDIT] It looks like nobody understood. I wanna save a string like
$string = If i say <?php count(array('lala'));?>
in a database and then render it. I can do it using
function render_php($string){
ob_start();
eval('?>' . $string);
$string = ob_get_contents();
ob_end_clean();
return $string;
}
The problem is that I does not reconize php code into "" (quotes) like
I say "<?php echo 'dada'; ?>"
$string = ($test === TRUE) ? 'lala' : 'falala';
There are lots of ways to do what it looks like you're trying to do (if I'm reading what you wrote correctly). The above is a ternary. If the condition evaluates to true then $string will be set to 'lala' else set to 'falala'.
If you're literally asking what you wrote, then use the eval() function. It takes a passed string and executes it as if it were php code. Don't include the <?php ?> tags.
function dropAllTables() {
// drop all tables in db
}
$string = 'dropAllTables();';
eval($string); // will execute the dropAllTables() function
[edit]
You can use the following regular expression to find all the php code:
preg_match_all('/(<\?php )(.+?)( \?>)/', $string, $php_code, PREG_OFFSET_CAPTURE);
$php_code will be an array where $php_code[0] will return an array of all the matches with the code + <?php ?> tags. $php_code[2] will be an array with just the code to execute.
So,
$string = "array has <?php count(array('lala')); ?> 1 member <?php count(array('falala')); ?>";
preg_match_all('/(<\?php )(.+?)( \?>)/', $string, $php_code, PREG_OFFSET_CAPTURE);
echo $php_code[0][0][0]; // <?php count(array('lala')); ?>
echo $php_code[2][0][0]; // count(array('lala'));
This should be helpful for what you want to do.
Looks like you are trying to concatenate. Use the concatenation operator "."
$string = "if i say " . $lala . " I wanna get " . $dada;
or
$string = "if i say {$lala} I wanna get {$dada}.";
That is what I get since your string looks to be a php variable.
EDIT:
<?php ?> is used when you want to tell the PHP interpreter that the code in those brackets should be interpreted as PHP. When working within those PHP brackets you do not need to include them again. So as you would just do this:
// You create a string:
$myString = "This is my string.";
// You decide you want to add something to it.
$myString .= getMyNameFunction(); // not $myString .= <?php getMyNameFunction() ?>;
The string is created, then the results of getMyNameFunction() are appended to it. Now if you declared the $myString variable at the top of your page, and wanted to use it later you would do this:
<span id="myString"><?php echo $myString; ?></span>
This would tell the interpreter to add the contents of the $myString variable between the tags.
Use token_get_all() on the string, then look for a T_OPEN_TAG token, start copying from there, look for a T_CLOSE_TAG token and stop there. The string between the token next to T_OPEN_TAG and until the token right before T_CLOSE_TAG is your PHP code.
This is fast and cannot fail, since it uses PHP's tokenizer to parse the string. You will always find the bits of PHP code inside the string, even if the string contains comments or other strings which might contain ?> or any other related substrings that will confuse regular expressions or a hand-written, slow, pure PHP parser.
I would consider not storing your PHP code blocks in a database and evaluating them using eval. There is usually a better solution. Read about Design Pattern, OOP, Polymorphism.
You could use the eval() function.
I'm working on a simple templating system. Basically I'm setting it up such that a user would enter text populated with special tags of the form: <== variableName ==>
When the system would display the text it would search for all tags of the form mentioned and replace the variableName with its corresponding value from a database result.
I think this would require a regular expression but I'm really messed up in REGEX here. I'm using php btw.
Thanks for the help guys.
A rather quick and dirty hack here:
<?php
$teststring = "Hello <== tag ==>";
$values = array();
$values['tag'] = "world";
function replaceTag($name)
{
global $values;
return $values[$name];
}
echo preg_replace('/<== ([a-z]*) ==>/e','replaceTag(\'$1\')',$teststring);
Output:
Hello world
Simply place your 'variables' in the variable array and they will be replaced.
The e modifier to the regular expression tells it to eval the replacement, the [a-z] lets you name the "variables" using the characters a-z (you could use [a-z0-9] if you wanted to include numbers). Other than that its pretty much standard PHP.
Very useful - Pointed me to what I was looking for...
Replacing tags in a template e.g.
<<page_title>>, <<meta_description>>
with corresponding request variables e,g,
$_REQUEST['page_title'], $_REQUEST['meta_description'],
using a modified version of the code posted:
$html_output=preg_replace('/<<(\w+)>>/e', '$_REQUEST[\'$1\']', $template);
Easy to change this to replace template tags with values from a DB etc...
If you are doing a simple replace, then you don't need to use a regexp. You can just use str_replace() which is quicker.
(I'm assuming your '<== ' and ' ==>' are delimiting your template var and are replaced with your value?)
$subject = str_replace('<== '.$varName.' ==>', $varValue, $subject);
And to cycle through all your template vars...
$tplVars = array();
$tplVars['ONE'] = 'This is One';
$tplVars['TWO'] = 'This is Two';
// etc.
// $subject is your original document
foreach ($tplVars as $varName => $varValue) {
$subject = str_replace('<== '.$varName.' ==>', $varValue, $subject);
}