views:

288

answers:

3

I'm just about ready to cry. I have read the php.net manual page, tried a dozen Google searches with various phrases, and scanned hundreds of stackoverflow threads. I have seen this method in use, but it just doesn't work for me. It seems so basic. I have a couple related questions or problems I don't know how to find answers to.

The important part of the PHP file looks like this:

switch() {
…other cases…
default:
  $tpl['title'] = "Newsletter Signup";
  $tpl['description'] = "Newsletter description";
  $tpl['page-content'] = file_get_contents('signup.html');
}

$tpl_src = addslashes(file_get_contents('index.tpl'));
eval("\$html = \"$tpl_src\";");
echo $html;

My index.tpl file includes lines like these:

<title>{$tpl['title']}</title>
<meta name="description" content="{$tpl['description']}" />
nav, etc…
<div id="main-content"> {$tpl['page-content']} </div>

I like how neat and clean the code is, without a whole bunch of extra <?=…?>'s.

First, when curly brackets {} appear in a string, what is that called? I might be able to look it up and learn how to use them if I knew.

Next, this just doesn't work at all. If I remove the single quotes from the variable keys, it's good, but php.net says you should never do that in case my name becomes a language constant at some point. Fair enough. But how do I fix this? I like using an array for the vars in case I want to build an evalTemplate subroutine and can just pass $tpl to it.

Lastly, $tpl['page-content'] doesn't print out. The variable is set okay; I can use echo $tpl['page-content'] to test, but it appears as a single blank line in the final HTML.

I'm sure there's just some aspect of the language I don't know yet. Any help is much appreciated!!

A: 

Usually you don't use the '' string delimiters in string variable expansion. I.e. "$tpl[content]" instead of "$tpl['content']".

As for as the braces, they delimit variable's when identifier characters may come straight before or after the name. For example:

$item = "Cup";
$text = "I smashed four $items"; // won't work
$text = "I smashed four {$item}s"; // will work.

// 2nd output: "I smashed four Cups"
Nick Bedford
Thanks so much for the braces info! That makes total sense, and now I see it used in just such ways.
Greg Perham
A: 

addslashes() adds slashes before both single- and double-quotes within the string. The code generated for your example would be

$html = "<title>{$tpl[\'title\']}</title>
<meta name=\"description\" content=\"{$tpl[\'description\']}\" />
nav, etc…¦
<div id=\"main-content\"> {$tpl[\'page-content\']} </div>";

And {$tpl[\'title\']} doesn't parse well.

VolkerK
A: 

As Volker pointed out, addslashes seems to be an issue. Try addcslashes instead. Also, I'd strongly recommend making this a function, to simplify sanitisation / parsing:

function render ($file, $vars)
{
    // .. extra sanitisation, validation, et al.
    $_html = '';
    $_raw_file = addcslashes (file_get_contents ($file), '"\\');
    extract ($vars, EXTR_SKIP);
    eval ('$_html = "'.$_raw_file.'"');

    return $_html;
}

And called thus:

switch() {
// …other cases…
default:
  $tpl['title'] = "Newsletter Signup";
  $tpl['description'] = "Newsletter description";
  $tpl['page-content'] = render ('signup.html');
}

echo render ('index.tpl', $tpl);

PS: The use of extract above means that your vars will simply be $title, not $tpl['title'], etc.

K Prime
I love this answer because it perfectly solves each problem I had and adds 'extract' and 'addcslashes' to my vocabulary! Thanks a bunch!
Greg Perham