Currently developing a "simple" template class, the problem is how would I execute PHP code within a string without using eval?
A following example is how my template class works:
$user = 'Dave';
ob_start();
include 'index.tpl';
$content = ob_get_clean(); // String
$pattern = sprintf('/%s\s*(.+?)\s*%s/s', '{{', '}}'); // replace with php tags
$new_content = preg_replace($pattern, '<?php echo $1; ?>', $content);
echo $new_content;
index.tpl
<html>
<head></head>
<body>
Hello {{ $user }}!
</body>
</html>
I get the following result:
Hello !
I don't want to use eval because how slow and bad it is to use, is there any other way of doing this? laravel blade engine does not use eval so there must be.
Thanks,
Joel.
You don't need to execute PHP Code. You replace your {{ $user }} with PHP code, which doesn't get executed anymore. So your HTML will look like this after the replace:
<?php echo "Dave" ?>
Your Browser thinks <?...> is an HTML-tag and thus doesn't display the correct name.
Solution:
Just replace {{ $user }} with Dave, why do you want to add more PHP Code?
I suggest to you when you assign a value to a variable, you should put it as a global variable like this;
$GLOBALS['My_Vars']['VarName'] = $Value;
when you retrevie the name of the variable from your code which is in your example $user, you change {{ $user }} to the value within $GLOBALS['My_Vars']['user']
in this case you don't need to use evel
Related
I'm using PHP as a template engine per this suggestion: https://stackoverflow.com/a/17870094/2081511
I have:
$title = 'My Title';
ob_start();
include('page/to/template.php');
$page = ob_get_clean();
And on page/to/template.php I have:
<?php
echo <<<EOF
<!doctype html>
<html>
<title>{$title}</title>
...
EOF;
?>
I'm trying to remove some of the required syntax from the template pages to make it easier for others to develop their own templates. What I would like to do is retain the variable naming convention of {$variable} but remove these lines from the template file:
<?php
echo <<<EOF
EOF;
?>
I was thinking about putting them on either side of the include statement, but then it would just show me that statement as text instead of including it.
Well, if you want a VERY simple templating solution, this might help
<?php
$title = 'My Title';
// Instead of including, we fetch the contents of the template file.
$contents = file_get_contents('template.php');
// Clone it, as we'll work on it.
$compiled = $contents;
// We want to pluck out all the variable names and discard the braces
preg_match_all('/{\$(\w+)}/', $contents, $matches);
// Loop through all the matches and see if there is a variable set with that name. If so, simply replace the match with the variable value.
foreach ($matches[0] as $index => $tag) {
if (isset(${$matches[1][$index]})) {
$compiled = str_replace($tag, ${$matches[1][$index]}, $compiled);
}
}
echo $compiled;
Template file would look like this
<html> <body> {$title} </body> </html>
How do you change the characters {{ }} into the equivalent echo function on a .php page, pretty much exactly like Laravel's blade.php pages (if it's possible at all)?
I have looked around and the only question that's similar that I seem to find is "How to use Laravel's blade without Laravel" which is not what I want.
Edit
I'm posting this new data because of apokryfos's answer.
This is the function I'm running:
function View($view)
{
$src = __DIR__.'/../../views/'.$view.'.view.php';
$destination= __DIR__.'/../../views/'.$view.'.view.php';
file_put_contents(
$destination,
str_replace(["{{","}}" ],[ "<?=", "?>" ], file_get_contents($src))
);
echo file_get_contents($destination);
}
From a controller, I use this code to call that function View('welcome');. It works by retrieving the page and that but the only problem is that it does not post the variable on the page, whereas accessing the page directly in the URL works.
This is the code on my page:
<?php
$item = 11;
?>
a php variable is {{ $item }}
It posts a php variable is and then nothing on the page, not sure why.
The simple thing to do is:
$src = "sourcefile.php";
$destination= "compiledsourcefile.php";
file_put_contents(
$destination,
str_replace(["{{","}}" ],[ "<?=", "?>" ], file_get_contents($src))
);
include $destination;
To echo this directly do:
$src = "sourcefile.php";
$text = str_replace(["{{","}}" ],[ "<?=", "?>" ], file_get_contents($src))
eval("?>".$text); //Things get a bit ugly here
echo $text;
The reason for "?>" is because eval starts in "PHP mode" by default but a properly written PHP file will explicitly set the areas where it needs to enter PHP mode and starts in HTML mode by default.
Note: Most people will say that using eval is bad, and while I do agree that using eval unchecked is indeed bad, using it on code which was read from a PHP file you've written is exactly the same as doing include on that file which is not as bad.
You can use this:
<?= $var ?>
It is the same as:
<?php echo $var ?>
I am using eval to execute php code that is coming from a database. The code is for meta tags and page title. One example looks like this (this is stored in a table):
$name . " test page title |".SiteSettings::getSiteNameAlternate();
And then in the controller I do this ($seo is an object that has the meta_title, and that element has the exact string from the db):
$pageTitle = isset($seo->meta_title) ? #eval("echo $seo->meta_title") : null;
I am using Larevel framework and I pass that page title to the blade template, and this works. The blade code
<title>{{ isset($page_title) ? $page_title : SiteSettings::defaultPageTitle() }}</title>
The issue is because the echo in the eval I get the page title on top of the page also.
I tried using print (dumb I know) and printf. Did not work. Any idea how to put the value of that eval in a variable without output on the screen?
$pageTitle = isset($seo->meta_title) ? #eval("return $seo->meta_title;") : null;
it will assign $seo->meta_title to $pageTitle if $seo->meta_title is set, and null otherwise.
A good way to store results is with ob_start, ob_get_contents and ob_end_clean
/*start buffering;*/
ob_start();
eval(echo isset($seo->meta_title) ? $seo->meta_title : "");
/* now catch the Buffer of the eval */
$pageTitle = ob_get_contents();
/* pageTitle contains now the value of the buffered echo */
/* stop buffering; */
ob_end_clean();
now use the Controller as you wanted
If I can understand your question correctly, the issue appears because you did an echo inside eval which will then executed. So instead, you should store the value of $seo->meta_title to variable and then let the view echo it.
In your controller, store meta title value as page title if isset, unless null
$pageTitle = null;
if (isset($seo->meta_title)) {
$metaTitle = '';
eval("\$metaTitle = \"$seo->meta_title\";");
$pageTitle = $metaTitle;
}
Then in your view
<title>{{ isset($page_title) ? $page_title : SiteSettings::defaultPageTitle() }}</title>
I had two script, one in .php and one in .tpl
I need to pass the variable in php to the tpl.
I tried this one, but nothinng works (but somehow
it works for one or two days, and after that,
it showed blank,
if i create another php script just to echo the variable, it works.
PHP Code:
<?php
$usdidr2 = "12610.198648";
$usdidr2 = number_format($usdidr,2,',','.');
echo $usdidr2;
session_start();
$regValue = $usdidr2;
$_SESSION['regUSDIDR1'] = $regValue;
?>
SMARTY Code:
<li>
<a href="example.php"><strong>
{php}
session_start();
$regValue = $_SESSION['regUSDIDR1'];
$regValue2 = number_format(45.99*$regValue,2,',','.');
echo "Rp. ".$regValue."";
print_r($regValue);
{/php}
</strong></a>
</li>
Here is the syntax to send data from php to tpl
$smarty->assign('variable name with which you can access the data in tpl', $php_data_you_want_to_send);
Update:
$smarty->assign('rate',$usdidr2);// you just need to write rate without $
You can access it in smarty like {$rate} if it is string
You can access it in smarty like {$rate|print_r} if it is array
You can use this syntax:
$res = "Hello World!";
$this->context->smarty->assign('result', $res);
And passing to .tpl file like this:
{$result}
Hope this helping you.
My Code:
<!-- {foreach from=$goods_cat.cat_id item=rec_cat name=f1}-->
<?php
**echo $rec_cat[id]; // get nothing, why?**
$smarty->assign('goods_cat_' . $rec_cat[id], assign_cat_goods($rec_cat[id], 4));
$smarty ->assign('cat_goods_nf' , 'goods_cat_' . $rec_cat[id]);
?>
<!--{foreach from=$cat_goods_nf item=goods}-->
{$goods.url}
<!--{/foreach}-->
<!--{/foreach}-->
I need the id of rec_cat ,so I use PHP Tags to get it,but Its display nothing? why ?How can I correct it?
Don't use <?php tag inside a template, but instead use {php} tag of Smarty :
http://www.smarty.net/docsv2/fr/language.function.php.tpl
Then you get your variables just like so :
$var = $this->get_template_vars('var');