Making a template with vars and file_get_contents in PHP - php

I have a php page that is reading from a file:
$name = "World";
$file = file_get_contents('html.txt', true);
$file = file_get_contents('html.txt', FILE_USE_INCLUDE_PATH);
echo $file;
In the html.txt I have the following:
Hello $name!
When I go to the site, I get "Hello $name!" and not Hello World!
Is there a way to get var's in the txt file to output their value and not their name?
Thanks,
Brian

The second param of file_get_contents has nothing to do with how to interpret the file - it's about which pathes to check when looking for that file.
The result, however, will always be a complete string, and you can only "reinterpolate" it with evial.
What might be a better idea is using the combination of include and output control functions:
Main file:
<?php
$name = "World";
ob_start();
include('html.tpl');
$file = ob_get_clean();
echo $file;
html.tpl:
Hello <?= $name ?>
Note that php tags (<?= ... ?>) in the text ('.tpl') file - without it $name will not be parsed as a variable name.

One possible approach with predefined values (instead of all variables in scope):
$name = "World";
$name2 = "John";
$template = file_get_contents ('html_templates/template.html');
$replace_array = array(
':name' => $name,
':name2' => $name2,
...
);
$final_html = strtr($template, $replace_array);
And in the template.html you would have something like this:
<div>Hello :name!</div>
<div>And also hi to you, :name2!</div>

To specifically answer your question, you'll need to use the 'eval' function in php.
http://php.net/manual/en/function.eval.php
But from a development perspective, I would consider if there was a better way to do that, either by storing $name somewhere more accessible or by re-evaluating your process. Using things like the eval function can introduce some serious security risks.

Related

How to get variables from a different PHP file without executing the code?

I am trying to loop through all the php files listed in an array called $articleContents and extract the variables $articleTitle and $heroImage from each.
So far I have the following code:
$articleContents = array("article1.php", "article2.php"); // array of all file names
$articleInfo = [];
$size = count($articleContents);
for ($x = 0; $x <= $size; $x++) {
ob_start();
if (require_once('../articles/'.$articleContents[$x])) {
ob_end_clean();
$entry = array($articleContents[$x],$articleTitle,$heroImage);
array_push($articlesInfo, $entry);
}
The problem is, the php files visited in the loop have html, and I can't keep it from executing. I would like to get variables from each of these files without executing the html inside each one.
Also, the variables $articleTitle and $heroImage also exist at the top of the php file I'm working in, so I need to make sure the script knows I'm calling the variables in the external file and not the current one.
If this is not possible, can you please recommend an alternative method?
Thanks!
Don't do this.
Your PHP scripts should be for your application, not for your data. For your data, if you want to keep it file-based, use a separate file.
There are plenty of formats to choose from. JSON is quite popular. You can use PHP's built-in serialization as well, which has support for more PHP-native types but is not as portable to other frameworks.
A little hacky but seems to works:
$result = eval(
'return (function() {?>' .
file_get_contents('your_article.php') .
'return [\'articleTitle\' => $articleTitle, \'heroImage\' => $heroImage];})();'
);
Where your_article.php is something like:
<?php
$articleTitle = 'hola';
$heroImage = 'como te va';
The values are returned in the $result array.
Explanation:
Build a string of php code where the code in your article scripts are wrapped inside a function that returns an array with the values you want.
function() {
//code of your article.php
return ['articleTitle' => $articleTitle, 'heroImage' => $heroImage];
}
Maybe you must do some adaptations to the strings due <?php ?> tags placements.
Anyway, this stuff is ugly. I'm very sure that it can be refactored in some way.
Your problem (probably) comes down to using parentheses with require. See the example and note here.
Instead, format your code like this
$articlesInfo = []; // watch your spelling here
foreach ($articleContents as $file) {
ob_start();
if (require '../articles/' . $file) { // note, no parentheses around the path
$articlesInfo[] = [
$file,
$articleTitle,
$heroImage
];
}
ob_end_clean();
}
Update: I've tested this and it works just fine.

Create a PHP file using PHP?

I'm planning about creating a simple script that will allow unexperienced in PHP users create a code files for one video game. I have two files, "code.txt" and "exec.php". The first file looks like this:
getglobal_move_call("TurnTarget")
getglobal_move_loadk_call("GenerateCSM", "15")
And "exec.php" creates a "temp.php", that imports the user made file. It's filled with "str_replace" functions, and results supposed to look like this:
<?
$temp_line = "TurnTarget(param1)";
file_put_contents($generated_output, $temp_line, FILE_APPEND);
$temp_line = "GenerateCSM(param1, 15)";
file_put_contents($generated_output, $temp_line, FILE_APPEND);
?>
But, when I echo my code after these replacements, I'm getting this:
<?
= "TurnTarget(param1)";
file_put_contents(User/Apple/Sites/Generate/Generated.txt, , FILE_APPEND);
= "GenerateCSM(param1, 15)";
file_put_contents(User/Apple/Sites/Generate/Generated.txt, , FILE_APPEND);
?>
As you can see, str_replace deleted all variables. Is there a solution to this?
It's because you use "" in your code, and PHP replaces $temp_line with it's actual value (null, because there is no such var).
To echo PHP code escape your $ with \
Live demo
$code = <<< PHP
\$temp_line = "TurnTarget(param1)";
file_put_contents(\$generated_output, \$temp_line, FILE_APPEND);
\$temp_line = "GenerateCSM(param1, 15)";
file_put_contents(\$generated_output, \$temp_line, FILE_APPEND);
PHP;
echo $code;
Fixed the problem by separating "$" symbol and variable's name.
str_replace("templine", "$"."templine", $code);

Setting php variable in html file using file_get_contents()

I have an automated email system set up to send an html file as an email. I bring that file into my email with PHPMailer, using
$mail->msgHTML(file_get_contents('mailContent.html'), dirname(__FILE__));
In the PHP source, before I add the mailContent.html, I have a variable $name='John Appleseed' (it is dynamic, this is just an example)
In the HTML file, I'm wondering if there is a way that I can use this $name variable in a <p> tag.
You can add a special string like %name% in your mailContent.html file, then you can replace this string with the value your want:
In mailContent.html:
Hello %name%,
…
In your PHP code:
$name='John Appleseed';
$content = str_replace('%name%', $name, file_get_contents('mailContent.html'));
$content will have the value Hello %name%, …, you can send it:
$mail->msgHTML($content, dirname(__FILE__));
You can also replace several strings in one call to str_replace() by using two arrays:
$content = str_replace(
array('%name%', '%foo%'),
array($name, $foo),
file_get_contents('mailContent.html')
);
And you can also replace several strings in one call to strtr() by using one array:
$content = strtr(
file_get_contents('mailContent.html'),
array(
'%name%' => $name,
'%foo%' => $foo,
)
);
You need to use a templating system for this. Templating can be done with PHP itself by writing your HTML in a .php file like this:
template.php:
<html>
<body>
<p>
Hi <?= $name ?>,
</p>
<p>
This is an email message. <?= $someVariable ?>
</p>
</body>
</html>
Variables are added using <?= $variable ?> or <?php echo $variable ?>. Make sure your variables are properly escaped HTML using htmlspecialchars() if they come from user input.
And then to the template in your program, do something like this:
$name = 'John Appleseed';
$someVariable = 'Foo Bar';
ob_start();
include('template.php');
$message = ob_get_contents();
ob_end_clean();
$mail->msgHTML($message, dirname(__FILE__));
As well as using PHP for simple templating, you can use templating languages for PHP such as Twig.
Here is a function to do it using extract, and ob_*
extract will turn keys into variables with their value of key in the array. Hope that makes sense. It will turn array keys into variables.
function getHTMLWithDynamicVars(array $arr, $file)
{
ob_start();
extract($arr);
include($file);
$realData = ob_get_contents();
ob_end_clean();
return $realData;
}
Caller example:
$htmlFile = getHTMLWithDynamicVars(['name' => $name], 'mailContent.html');
In one of my older scripts I have a function which parses a file for variables that look like {{ variableName }} and have them replaced from an array lookup.
function parseVars($emailFile, $vars) {
$vSearch = preg_match_all('/{{.*?}}/', $emailFile, $vVariables);
for ($i=0; $i < $vSearch; $i++) {
$vVariables[0][$i] = str_replace(array('{{', '}}'), NULL, $vVariables[0][$i]);
}
if(count($vVariables[0]) == 0) {
throw new TemplateException("There are no variables to replace.");
}
$formattedFile = '';
foreach ($vVariables[0] as $value) {
$formattedFile = str_replace('{{'.$value.'}}', $vars[$value], $formattedFile);
}
return $formattedFile;
}
Do you have the $name variable in the same file where you send the mail? Then you can just replace it with a placeholder;
Place __NAME__ in the HTML file where you want the name to show up, then use str_ireplace('__NAME__', $name, file_get_contents('mailContent.html')) to replace the placeholder with the $name variable.

How to read content of one.php and write into two.php

I have one file one.php
<?php //just a php function doen't have to do any thing with the question
function B(){
}
?>
Through php I want to read one.php as it is and write into two.php as it is..
Note- '<' getting converted into '$lt;'
Answer to it is
<?php
$text = file_get_contents("one.php");
file_put_contents("two.php", $text);
?>
Now further what I want is add one more php function say function A(){} to the content of one.php and write it into two.php
That's fairly simple nowadays :-).
$text = file_get_contents("one.php");
file_put_contents("two.php", $text);
For more parameters to the methods, see the PHP.net documentation on file-get-contents and file-put-contents.
If you are after an exact copy of "one.php", then use PHP's "copy" method.
copy('one.php', 'two.php');
In regards to your edited question, the solution is:
$content = file_get_contents('one.php');
$content .= 'function A() {}';
file_put_contents('two.php', $content, FILE_APPEND);
$contents = file_get_contents('one.php');
$newContents = htmlspecialchars ($contents);
file_put_contents('two.php', $newContents);
Your are mixing up strings and resources a little bit. file_get_contents() stores the page in a string. It's easier to use file_put_contents in that case.
<?php
file_put_contents("two.php", htmlspecialchars (file_get_contents('one.php')));
// file_get_contents(): Stores the content of one.php into a string
// htmlspecialchars: encodes html
// file_put_contents(): Writes the string into two.php
?>
In your case, an even easier solution would be:
<?php
include("one.php");
?>

How do you eval() a PHP code through multiple levels?

I have this code:
$layout_template = template_get("Layout");
$output_template = template_get("Homepage");
$box = box("Test","Test","Test");
eval("\$output = \"$layout_template\";");
echo $output;
In the $template_layout variable is a call for the
variable $output_template, so then the script moves onto the $output_template variable
But it doesn't go any further, inside the $output_template is a call to the variable $box, but it doesn't go any further than one level
I would never want nested eval(), and especially not in any recursive logic. Bad news. Use PHP's Include instead. IIRC eval() creates a new execution context, with overhead whereas include() doesn't.
If you have buffers such as:
<h1><?php echo $myCMS['title']; ?></h1>
I sometimes have files like Index.tpl such as above that access an associative array like this, then you just do in your class:
<?php
class TemplateEngine {
...
public function setvar($name, $val)
{
$this->varTable[$name]=make_safe($val);
}
....
/* Get contents of file through include() into a variable */
public function render( $moreVars )
{
flush();
ob_start();
include('file.php');
$contents = ob_get_clean();
/* $contents contains an eval()-like processed string */
...
Checkout ob_start() and other output buffer controls
If you do use eval() or any kind of user data inclusion, be super safe about sanitizing inputs for bad code.
It looks like you are writing a combined widget/template system of some kind. Write your widgets (views) as classes and allow them to be used in existing template systems. Keep things generic with $myWidget->render($model) and so on.
I saw this on the PHP doc-user-comments-thingy and it seems like a bad idea:
<?php
$var = 'dynamic content';
echo eval('?>' . file_get_contents('template.phtml') . '<?');
?>
Perhaps someone can enlighten me on that one :P

Categories