Replacing string coming from the DB with Smarty - php

I am using Smarty for my template engine.
But I have an issue that is driving me crazy, so please provide a concrete example if you have the solution.
I have some HTML saved in the mySQL DB. When I get it I want to replace {$foo} with the correct value of the variable.
I am trying to do this because I have a multi-language website. So lets assume that this is the code given into the variable $content coming from the DB:
$content = <div id="help">{$lang['helpmeout'}</div>
<div id="hello">{$lang['hello']}</div>
Now assuming that the content above is coming from the DB and that is stored into the $content variable, how do I say to smarty to catch the variables inside the brackets {} and to treat them as normal PHP code? I cannot really get it working.
Nobody seems to have a working solution for this.
Please help

I don't know how Smarty works. Consider this snippet to parse the php variables:
$lang = array('helpmeout' => 'helpMeOut', 'hello' => 'hi');
$content = '<div id="help">{$lang[\'helpmeout\']}</div>
<div id="hello">{$lang[\'hello\']}</div>';
eval('$c = "'.str_replace('"', '\"', $content).'";');
echo $c;
The point here is that evaluating $c = "$content" (scaping ") will parse the php variables.
I hope that helps.

Smarty 3 knows the string resource. If you need to disable certain Smarty features for this, have a look at Smarty Security.

Related

PHP echo-ing a PHP code inside an echo

I'm quite new here. I'm trying to make a blog/journal site that allows users to post their own journal. I'm still quite reluctant on making it because I am really afraid of malicious code injections.
So here's a sample code:
<?php
$test = "<b>blah</b>"; //User input from SQL
echo "$test";
?>
What will come out is just the word "blah" in bold right? What I was trying to achieve was to echo "<b>blah</b>" instead. I don't want people to put some PHP codes that can actually mess up my whole web page. Please keep in mind that the variable $test is actually a MYSQL query, so that variable will be needed as an example. I know you can do echo '$test'; but it just comes out as "$test" instead. I feel like pulling my hair out I can't figure it out yet.
The second solution I know of is the htmlspecialchars(); function, but I want the strings to display as what I typed, not the converted ones...
Is there any way I can do that?
I think the OP wants the HTML itself to be output to the page, and not have the tags stripped. To achieve this, you can run the string first through htmlentities()
$test = '<b>blah</b>';
echo htmlentities($test);
This will output:
<b>blah</b>
Which will render in the page as
<b>blah</b>
Echo don't execute PHP code from string. This is impossible and this is not security hole in your code.
You can use a template engine like Twig for exemple.
If htmlspecialchars(); is not the one you are looking for, try the header() option.
header('Content-type: text/plain');
When you are gonna give <b>Hi</b> to a browser, it will be displayed in Bold and not the text be returned. But you can try this way, outputting it inside a <textarea></textarea>.
Or the other way is to use htmlentities():
<?php
$test = "<b>blah</b>"; //User input from SQL
echo htmlentities("$test");
?>

Using variable type variables as array names in php

I'm trying to make a dynamic menu in my web, in which only some pages from each section will appear.
The code I wrote was:
$menulist=array();
$menulist[1]='file1%#16';
$menulist[2]='file2%#9';
$menulist[3]='file3%#19';
$menulist[4]='file4%#8';
$menulist[5]='file5%#13';
$menulist[6]='file6%#14';
$menulist[7]='file7%#10';
$menulist[8]='file8%#23';
$menulist[9]='file9%#19';
$menulist[10]='file10%#18';
$menulist[11]='file11%#12';
function actualizaciones($matriz)
{
$linea=explode("%#",$matriz);
echo '<li><a href="first_chunk_of_URL'.$linea[0].'middle_chunk_of_url'.$linea[1].'last_chunk_of_URL">'.${$linea[0]}[$linea[1]].'</li>;
}
echo '<ul>';
array_walk($menulist,'actualizaciones');
echo '</ul>';
Every $linea[0] string is the name of another array (not shown in this code) which contains the text that should be in every possible link corresponding to every key passed by $linea[1].
I must have done something wrong, because the hyperlinks work fine but there's no text showing on them.
use the simple character like below
echo '<li><a href="first_chunk_of_URL'.$linea[0].'middle_chunk_of_url'.$linea[1].'last_chunk_of_URL">'.${$linea[0]}[$linea[1]].'<li>';
and the problem in your code is
.'</li>;
^^^^^
here is the problem it should be
.'</li>';
If I'm reading the question right, you're asking how to use variable variables in PHP.
This can be done using the double-dollar syntax - ie $$linea[0]. See the PHP manual for more info: http://uk.php.net/manual/en/language.variables.variable.php
But if that is what you're doing, I would say you're not writing good code: if variable variables are involved, there's almost always a better way of doing it.
Can't really offer much better assistance here without understanding more about what you're trying to do, but it sounds like you should be using subarrays rather than separate named variables for everything.
Hope that helps.

Echo'ing a "{FORUM_NAME}" and Ignoring the "{}"

I'm looking for something that Is really hard for me to do.. I really tried to search all over the net for Solution, But I couldn't seem to find any. I also tried doing this for hours.
What I'm doing: Making a theme for PHPBB2, Installed a MOD that can include PHP in themes.
What is the problem: When I'm doing {} tags in php, It just can't echo those tags.
Let's say I have a function that creates a Table for me, like that:
CreateMyTable(Name,Size,Color);
I put in the function those strings:
CreateMyTable("{FORUM_NAME}",1000,red);
The title stays blank, I actually want it to echo {FORUM_NAME}.
How can I do this?
P.S: I can't do this
CreateMyTable(?>{FORUM_NAME}<?php , 1000, red);
It's not going to work becuase <? = <!-- PHP --> , ?> = <!-- ENDPHP -->.
Thanks for your help :)
If you look in the PHPbb2 template class, you'll find that the template is simply an evaluated set of PHP using the eval() function. You can either print the contents of the PHP before it is parsed using eval() and then use the variable name that the template gives, IE something like (which may not work depending how your template is setup):
CreateMyTable(((isset($this->_tpldata['.'][0]['FORUM_NAME'])) ? $this->_tpldata['.'][0]['FORUM_NAME'] : '' ),1000,randomcolor());
Please note, in order to do it similar to the way above you'd actually have to insert this into your template class.
An much better solution is to avoid using the mod that allows PHP in templates and use JavaScript in the templates to create the function, then print a call to that JavaScript function.
This will work:
CreateMyTable(FORUM_NAME,1000,red);
I also noticed that red is used without quotes - is this also a constant? If it's a variable it needs to have a $ in front of it. If it's a string it should be between quotes.
CreateMyTable(FORUM_NAME,1000,"red");

Run PHP coming into a mySQL result

This is maybe about the 4 time I ask this question all over the web without having a working solution.
It is driving me crazy.
I will try to make it as easier as possible to understand.
I have some code inside a database table, that looks like this:
<div> Hello my name is {$name}</div>
<span> I come from {$city}</span>
<div>I am {$age} years old</div>
I repeat, this text come from a mySQL table that I SELECT with the following code:
function getPageContent($page) {
$q='SELECT * FROM pages WHERE Page="'.$page.'"';
$r=mysql_query($q) or die(mysql_error());
while($row = mysql_fetch_array($r)) {
$content= $row['Content'];
}
return $content;
}
As you may see there are some PHP variables in the above code, such as {$age} or {$city}, they are only samples because I won't know the exact content.
What I need to do is to find a way for PHP to get the contents of the $content variable ( string coming from the DB SELECT ), to recognize the variables inside the brackets {$foo} as normal PHP variables and to run them before echoing the final code.
As you may see the $content variable may have different and unknown variables inside it, so I must find a way to get those variables whatever they represent.
I do not know if the right thing to use here is eval(). But seems that eval() works only with something like {echo 'value'} and not with variables {$foo}, or {echo $foo} because variables won't be recognized at all.
Does anyone have a solution for this?
This is driving me crazy.
The concept is to give to the users the possibility to enter HTML text inside my mySQL DB and to include whatever PHP code they want inside brackets {}. This can be very useful for example for multi-language websites..etc..
I hope you understand my point.
Thanks
Do not use eval for this. Just do a simple search and replace.
From your question, tt's hard to understand where exactly the values for $name, $city and $age are stored. So, I'll just start from the point where you've retrieved that info. Let's say it's something like this:
$content = '<div> Hello my name is {$name}</div>
<span> I come from {$city}</span>
<div>I am {$age} years old</div>
';
$city = 'Kansas City';
echo str_replace('{$city}', $city, $content);
Also, in the sample code you've provided, the $content variable keeps getting over-written on each iteration of the while loop. Perhaps, that's what you want to happen or perhaps you wish to concatenate it.
Edit
After reading some of your comments, it seems that you will need a more dynamic solution. You can do so with something along the lines of:
if (preg_match_all('/{\$\w+}/', $content, $matches)) {
foreach ($matches[0] as $var) {
// var now contains the {$variableName}.
}
}
This will find the variables within your HTML, which you can then loop over, comparing against your file that contains the actual name/value pairs. Then use str_replace as shown above.
Why not just do this?
<div> Hello my name is <?=$name?></div>
<span> I come from <?=$name?></span>
<div>I am <?=$age?> years old</div>
For this to work, of course, you need the short_open_tag directive enabled. You can accomplish the same thing in more code without this enabled too:
<div> Hello my name is <?php echo $name ?></div>
<span> I come from <?php echo $name ?></span>
<div>I am <?php echo $age ?> years old</div>
You should really watch out for malicious users gaining access to this script though, because the way you envisioned it, they would be able to execute any code they so desired. Be sure to sanitize input and output of this script!

how to eval() a segment of a string

I have a string that has HTML & PHP in it, when I pull the string from the database, it is echo'd to screen, but the PHP code doesn't display. The string looks like this:
$string = 'Hello <?php echo 'World';?>';
echo $string;
Output
Hello
Source Code
Hello <?php echo 'World';?>
When I look in the source code, I can see the php line there. So what I need to do is eval() just the php segment that is in the string.
One thing to consider is that the PHP could be located anywhere in the string at any given time.
* Just to clarify, my PHP config is correct, this is a case of some PHP being dumped from the database and not rendering, because I am echo'ing a variable with the PHP code in it, it fails to run. *
Thanks again for any help I may receive.
$str = "Hello
<?php echo 'World';?>";
$matches = array();
preg_match('/<\?php (.+) \?>/x', $str, $matches);
eval($matches[1]);
This will work, but like others have and will suggest, this is a terrible idea. Your application architecture should never revolve around storing code in the database.
Most simply, if you have pages that always need to display strings, store those strings in the database, not code to produce them. Real world data is more complicated than this, but must always be properly modelled in the database.
Edit: Would need adapting with preg_replace_callback to remove the source/interpolate correctly.
You shouldn't eval the php code, just run it. It's need to be php interpreter installed, and apache+php properly configured. Then this .php file should output Hello World.
Answer to the edit:
Use preg_replace_callback to get the php part, eval it, replace the input to the output, then echo it.
But. If you should eval things come from database, i'm almost sure, it's a design error.
eval() should work fine, as long as the code is proper PHP and ends with a semicolon. How about you strip off the php tag first, then eval it.
The following example was tested and works:
<?php
$db_result = "<?php echo 'World';?>";
$stripped_code = str_replace('?>', '', str_replace('<?php', '', $db_result));
eval($stripped_code);
?>
Just make sure that whatever you retrieve from the db has been properly sanitized first, since you're essentially allowing anyone who can get content into the db, to execute code.

Categories