Reputation:
I have a PHP script with some variables set in the global namespace:
$domain = 'example.com';
$hostname = 'www.' . $domain;
I am reading an external file into a string variable in my script using file_get_contents:
$file_contents = file_get_contents('external_file.tpl');
The external file (and the string $file_contents
) contains placeholders which correspond to variable names.
127.0.0.1 {{domain}} {{hostname}}
I would like to have all the placeholders in the variable $file_contents
replaced with their respective PHP variables already set. I want this to work generically (without hard-coding placeholder / variable names). I do not want to edit the file, just the contents of the string.
What's the easiest way to do this?
Upvotes: 1
Views: 231
Reputation:
Alright guys, I took some bits and pieces from other answers and came up with what I think is the best solution for me:
$domain = 'example.com';
$hostname = 'www.' . $domain;
$file_contents = '127.0.0.1 {{domain}} {{hostname}}';
$result = preg_replace_callback(
"/{{(.+?)}}/",
function ($matches) {
return $GLOBALS[$matches[1]];
},
$file_contents
);
This answer combines ideas from @TonyDeStefano, @dops, and @fschmengler. So please up-vote them. @BugaDániel also helped with his comments.
Upvotes: 1
Reputation: 800
You could use a preg_replace_callback
to do this, you will need to put your replacements into an array though.
e.g
$domain = 'example.com';
$newString = preg_replace_callback(
'/{{([^}}]+)}}/',
function ($matches) {
foreach ($matches as $match) {
if (array_key_exists($match, $_GLOBALS))
return $replace[$match];
}
},
$file_contents
);
The matches returned for that particular regex would be an array
array [
'{{hostname}}',
'hostname',
'{{domain}}',
'domain'
]
Which is why we would do a check with array_key_exists
Upvotes: 1
Reputation: 24551
Disclaimer: I don't think it's a good idea to allow arbitrary variables to be used in whatever this template is going to be.
The function get_defined_vars()
creates an array of all currently available variables in the form variable_name => value
(THIS INCLUDES SUPERGLOBALS LIKE $_SERVER AND $_GET!)
The string translation function strtr(string $str, array $replace_pairs)
can replace keys of an associative array with their values in a string.
Together they form a mighty but dangerous alliance. The following code will replace domain
with the value of $domain
and so on:
echo strtr(file_get_contents('external_file.tpl'), get_defined_vars());
Adding {{...}}
is possible with a little extra effort:
$vars = get_defined_vars();
$replace = array();
foreach ($vars as $key => $value) {
$replace['{{' . $key . '}}'] = $value;
}
echo strtr(file_get_contents('external_file.tpl'), $replace);
Use it responsibly! Remember not to trust any user input.
Upvotes: 1
Reputation: 2183
This will do the work for global variables
<?php
$domain = 'example.com';
$hostname = 'www.' . $domain;
$file_contents = "127.0.0.1 {{domain}} {{hostname}}";
foreach($GLOBALS as $key => $value){
if(!is_string($value) && !is_numeric($value)){
continue;
}
$file_contents = str_replace('{{'.$key.'}}', $value, $file_contents);
}
var_dump($file_contents);
Will output:
string '127.0.0.1 example.com www.example.com' (length=37)
Upvotes: 0
Reputation: 829
Like so:
$matches = array();
preg_match('/\{\{([a-zA-Z0-9_]+)\}\}/', $file_contents, $matches);
foreach ($matches as $match)
{
// You might want to check to make sure the variable is a string
if (isset($GLOBALS[$match]))
{
str_replace('{{'.$match.'}}', $GLOBALS[$match], $file_contents);
}
}
Upvotes: 2
Reputation: 747
You could simply use str_replace
to do this. Since you know what the place holders are going to be, try something like this:
str_replace(['{{domain}}','{{hostname}}'],[$domain, $hostname], $file_contents);
Upvotes: 0