Using fetch() without Smarty? - php

Smarty 3 has an option to set (assign) a variable and then include (fetch) a file to a new variable.
How can I do this without the Smarty class? file_get_contents would not work, is there something else?
For example, this is the Smarty code:
<?php
$variable = 'Hello World';
$smarty->assign('variable', $variable);
$content = $smarty->fetch('content.tpl'); // content.tpl have "{$variable}" inside
echo '<script>document.write("' . $content . '")</script>'; // this will output <script>document.write("Hello World")</script>
?>
I want to do it without Smarty:
<?php
$variable = 'Hello World';
$content = file_get_contents('content.php'); // content.php have "echo $variable;" inside
echo '<script>document.write("' . $content . '")</script>';// this needs to output <script>document.write("Hello World")</script>, but it's outputing echo $variable;
?>

You can take advantage of buffering tricks.
function fetch($filename, array $vars) {
ob_start(); // Start output buffering
extract($vars); // Extract variables
require($filename); // Include a file
return ob_get_clean(); // Pass variables to included filename and return output as a string
}
And then you can use it like this:
$content = fetch('content.php', array(
'variable' => 'Hello World',
'name' => 'John Doe',
));
echo $content;
My content.php looks like as follows:
<div>
<b><?php echo $variable; ?></b>, you're logged in as <?php echo $name; ?>
</div>
It outputs Hello World, you're logged in as John Doe

Related

How to capture HTML for a PHP variable

I have dozens of templates elaborated by a web designer. They are primarily HTML, with a few PHP tags and data. The problem is that I need to re-use those templates (tpl.php) to send email, and the email body (through PHPMailer) is a variable. I have succeeded to fill a variable with the HTML output in the code example (adapted). My question is: should I redo all the templates or is this a valid approach?
<?php
print "This will print just the 'hello world' output. I don't need to print the function as it has no return value<br />";
hola_mundo(); // I directly call the function and it outputs HTML to the screen
print "<br />";
// Now the assignment to the variable.
ob_start(); // I silence the output to screen
hola_mundo();
$string = ob_get_contents(); // I capture the buffer
ob_end_clean(); // I restore the output to screen
print "Now I print the string variable to demonstrate it has captured the HTML ";
print $string;
function hola_mundo(){
?><font color="red"<b>HOLA MUNDO CRUEL</b></font><?php
} // function
?>
The more logical approach would be to have this function (which I do not have and should redo for dozens of templates):
<?php
$string = hola_mundo();
print $string;
function hola_mundo(){
$string = '<font color="red"<b>HOLA MUNDO CRUEL</b></font>';
return $string
} // function
?>
Do you mean this?
function getTemplate($file) {
ob_start();
include $file;
return ob_get_clean();
}
// Example usage:
$string = getTemplate('templates/tpl.php');
tpl.php will be executed as a PHP file.
You can even pass variables to the template:
function getTemplate($file, $variables=array()) {
extract($variables);
ob_start();
include $file;
return ob_get_clean();
}
// Example usage:
$string = getTemplate('templates/tpl.php', array('message' => 'Hello world!'));
This will extract 'Hello world' into the function scope, making it available as the $message variable to the template.

php evaluate code before getting file content

I have a file B590.php which is having a lot of html code and some php code (eg logged in username, details of user).
I tried using $html = file_get_content("B590.php");
But then $html will have the content of B90.php as plain text(with php code).
Is there any method where I can get the content of the file after it has been evaluated?
There seems to be many related questions like this one and this one but none seems to have any definite answer.
You can use include() to execute the PHP file and output buffering to capture its output:
ob_start();
include('B590.php');
$content = ob_get_clean();
function get_include_contents($filename){
if(is_file($filename)){
ob_start();
include $filename;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
return false;
}
$html = get_include_contents("/playbooks/html_pdf/B580.php");
This answer was originally posted on Stackoverflow
If you use include or require the file contents will behave as though the current executing file contained the code of that B590.php file, too. If what you want is the "result" (ie output) of that file, you could do this:
ob_start();
include('B590.php');
$html = ob_get_clean();
Example:
B590.php
<div><?php echo 'Foobar'; ?></div>
current.php
$stuff = 'do stuff here';
echo $stuff;
include('B590.php');
will output:
do stuff here
<div>Foobar</div>
Whereas, if current.php looks like this:
$stuff = 'do stuff here';
echo $stuff;
ob_start();
include('B590.php');
$html = ob_get_clean();
echo 'Some more';
echo $html;
The output will be:
do stuff here
Some more
<div>Foobar</div>
To store evaluated result into some variable, try this:
ob_start();
include("B590.php");
$html = ob_get_clean();
$filename = 'B590.php';
$content = '';
if (php_check_syntax($filename)) {
ob_start();
include($filename);
$content = ob_get_clean();
ob_end_clean();
}
echo $content;

How to change title of the page after including header.php?

page.php:
<?php
include("header.php");
$title = "TITLE";
?>
header.php:
<title><?php echo $title; ?></title>
I want my title to be set after including the header file. Is it possible to do this?
expanding on Dainis Abols answer, and your question on output handling,
consider the following:
your header.php has the title tag set to <title>%TITLE%</title>;
the "%" are important since hardly anyone types %TITLE% so u can use that for str_replace() later.
then, you can use output buffer like so
<?php
ob_start();
include("header.php");
$buffer=ob_get_contents();
ob_end_clean();
$buffer=str_replace("%TITLE%","NEW TITLE",$buffer);
echo $buffer;
?>
and that should do it.
EDIT
I believe Guy's idea works better since it gives you a default if you need it, IE:
The title is now <title>Backup Title</title>
Code is now:
<?php
ob_start();
include("header.php");
$buffer=ob_get_contents();
ob_end_clean();
$title = "page title";
$buffer = preg_replace('/(<title>)(.*?)(<\/title>)/i', '$1' . $title . '$3', $buffer);
echo $buffer;
?>
1. Simply add $title variable before require function
<?php
$title = "Your title goes here";
require("header.php");
?>
2. Add following code into header.php
<title><?php echo $title; ?></title>
What you can do is, you store the output in a variable like:
header.php
<?php
$output = '<html><title>%TITLE%</title><body>';
?>
PS: You need to remove all echos/prints etc so that all possible output is stored in the $output variable.
This can be easely done, by defining $output = ''; at the start of the file and then find/replace echo to $output .=.
And then replace the %TITLE% to what you need:
<?php
include("header.php");
$title = "TITLE";
$output = str_replace('%TITLE%', $title, $output);
echo $output;
?>
Another way is using javascript in your code, instead of:
<title><?php echo $title; ?></title>
Put this in there:
<script type="text/javascript">
document.title = "<?=$title;?>"
</script>
Or jQuery, if you prefer:
<script type="text/javascript">
$(document).ready(function() {
$(this).attr("title", "<?=$title;?>");
});
</script>
Expanding a little on we.mamat's answer,
you could use a preg_replace instead of the simple replace and remove the need for a %title% altogether. Something like this:
<?php
ob_start();
include("header.php");
$buffer=ob_get_contents();
ob_end_clean();
$title = "page title";
$buffer = preg_replace('/(<title>)(.*?)(<\/title>)/i', '$1' . $title . '$3', $buffer);
echo $buffer;
?>
you can set using JavaScript
<script language="javascript">
document.title = "The new title goes here.";
</script>
Add this code on top your page
<?php
$title="This is the new page title";
?>
Add this code on your Template header file (include)
<title><?php echo $title; ?></title>
It's very easy.
Put this code in header.php
<?
$sitename = 'Your Site Name'
$pagetitle;
if(isset($pagetitle)){
echo "<title>$pagetitle." | ". $sitename</title>";
}
else {
echo "<title>$sitename</title>";
}
?>
Then in the page put there :
<?
$pagetitle = 'Sign up'
include "header.php";
?>
So if you are on Index.php , The title is Your Site Name.
And for example if you are on sign up page , The title is Sign up | Your Site Name
Every Simple just using a function , I created it .
<?
function change_meta_tags($title,$description,$keywords){
// This function made by Jamil Hammash
$output = ob_get_contents();
if ( ob_get_length() > 0) { ob_end_clean(); }
$patterns = array("/<title>(.*?)<\/title>/","<meta name='description' content='(.*)'>","<meta name='keywords' content='(.*)'>");
$replacements = array("<title>$title</title>","meta name='description' content='$description'","meta name='keywords' content='$keywords'");
$output = preg_replace($patterns, $replacements,$output);
echo $output;
}
?>
First of all you must create function.php file and put this function inside ,then make require under the MetaTags in Header.php .
To use this function change_meta_tags("NEW TITLE","NEW DESCRIPTION",NEW KEYWORDS); .
Don't use this function in Header.php !! just with another pages .
Use a jQuery function like this:
$("title").html('your title');

PHP code dynamic evaluation

Imagine we have 2 files, one called 1.php with the following code:
<?php
$hello = "Hello from 1";
?>
and 2.php with the following code:
<?php
function LoadPage( $page )
{
$f = fopen( $page, 'r+' );
$content = fread( $f, filesize($page) );
fclose( $f );
return $content;
}
function GetEvalContent( $content )
{
$var = "";
ob_start();
eval( "?>" . $content . "<?" );
$var = ob_get_contents();
ob_end_clean();
return $var;
}
$hello = "hello from 2";
echo $hello . '<br/>';
$content = LoadPage( '1.php' );
GetEvalContent( $content );
echo $hello;
?>
So what the 2.php does is load the content of 1.php and evaluate the php code inside it. Now what I want to do is during the evaluation of 1.php, variable $hello changes to "hello from 1". However if you execute 2.php you always get:
"hello from 2"
"hello from 2"
instead of getting
"hello from 2"
"hello from 1"
Has anyone encountered this problem before and if so, how would you fix it?
There is a much easier way to do this. Use PHP's include.
1.php
<?php
$hello = "Hello from 1";
?>
2.php
<?php
$hello = "hello from 2";
echo $hello;
include '1.php';
echo $hello;
?>
UPDATE (not tested):
function includeFile($file){
global $hello; // Use the global variable $hello
// this will make the include sets $hello correctly
ob_start();
include $file; // Remember any variables set here will be in this scope,
// not the global scope (unless you add them to the global line above)
$var = ob_get_contents(); // This will contain anything echoed to the screen
// from the included file
ob_end_clean();
return $var;
}
$hello = "hello from 2";
echo $hello;
$file = '1.php';
$output = includeFile($file);
echo $hello;
echo $output;
You're doing your eval() within a function, so the $hello in the included file will be part of only the function's scope. It will not affect the $hello that's defined outside the function (which is global scope).
You'd need to put the global keyword into your included file, unless you want to write your own PHP parser to figure out what variables are being defined in the included file and auto-globalize them.
However, in the bigger picture... WHY? eval is a horribly evil ugly construct, and you're opening yourself up to a world of debugging pain, let alone the security issues.
Have you considered using require or include? PHP Manual
Example:
$hello = "Hello from 2";
echo $hello;
include("1.php");
echo $hello;
try to use $GLOBALS['hello'] instead of $hello
PS: Don't forget eval is evil ;)

php: simple template engine

I have a function called load_template()
this function has two parameters
$name => the name of the template
$vars => array of key => value variables to be replaced in the template.
the way I want this to work is.
in the template ('test') I want to be able to write
<?php echo $title; ?>
then call
load_template('test', array('title' => 'My Title'));
and have it fill it out.
how can I do this?
Output buffering method.
I have come up with the code below.
I am sure it can be improved.
public static function template($name, $vars = array()) {
if (is_file(TEMPLATE_DIR . $name . '.php')) {
ob_start();
extract($vars);
require(TEMPLATE_DIR . $name . '.php');
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
throw new exception('Could not load template file \'' . $name . '\'');
return false;
}
function load_template($name, $vars)
{
extract($vars);
include $name;
}
Wrap with ob_start and ob_get_clean if you want to capture the output in a variable.
Something like this?
function load_template($name, $vars)
{
include('template/'.$name.'.tpl'); //.tpl, .inc, .php, whatever floats your boat
}
and in template/whatever.tpl you'd have:
...
<title><?php echo $vars['title'] ?></title>
...
...
<?php if (!empty($vars['content'])): //template still needs to know if the content is empty to display the div ?>
<div id="content">
<?php echo $vars['content']; ?>
</div>
<?php endif; ?>
...
Of course, that assumes the output being printed directly.
You could have the tpl file print directly, or produce a string, or buffer the output from the tpl file and return it from load_template

Categories