tags:

views:

458

answers:

3

Hi all,

I'm messing around with templating and I've run into a situation where I need to echo to the browser a template that contains html & php. How do I evaluate the PHP and send it to the browser?

So here's an example (main.php):

 <div id = "container">
  <div id="head">
   <?php if ($id > 10): ?>
    <H3>Greater than 10!</H3>
   <?php else: ?>
    <H3>Less than 10!</H3>
   <?php endif ?>
  </div>
            </div>

And then in the template.php:

   <?php
           $contents; // Contains main.php in string format
           echo eval($contents); // Doesn't work... How do I do this line??
   ?>

EDIT: My template also allows you to inject data from the controller Smarty-style. Would an output buffer allow me to do this and then evaluate my php. The ideal is that it does a first-pass through the code and evaluates all the tags in first, then runs the php. This way I can create loops and stuff from using data sent from my controller.

So maybe a more complete example: 
    <div id = "container">
            <div id = "title">{$title}</div> <!-- This adds data sent from a controller -->
            <div id="head">
                <?php if ($id > 10): ?>
                    <H3>Greater than 10!</H3>
                <?php else: ?>
                    <H3>Less than 10!</H3>
                <?php endif ?>
            </div>
    </div>

Thanks!

+1  A: 

Use output buffering instead. eval() is notoriously slow.

main.php:

<div id="container">
    <div id="title"><?php echo $title; ?></div><!-- you must use PHP tags so the buffer knows to parse it as such -->
    <div id="head">
     <?php if ($id > 10): ?>
      <H3>Greater than 10!</H3>
     <?php else: ?>
      <H3>Less than 10!</H3>
     <?php endif ?>
    </div>
</div>


Your file:

$title = 'Lorem Ipsum';
$id = 11;

ob_start();
require_once('main.php');
$contents = ob_get_contents();
ob_end_clean();

echo $contents;

The output of this will be:

Lorem Ipsum

Greater than 10!

Josh Leitzel
I clarified what my template does, would this still work?
Matt
Yes, you can use variables you've already declared in the template. You can't, however use {$title} like you did - this will just show that text literally. You have to tell the template that that's PHP. I've updated my answer to demonstrate.
Josh Leitzel
+1  A: 

Do not read the file, but include it and use output bufferig to capture the outcome.

ob_start();
include 'main.php';
$content = ob_get_clean();

// process/modify/echo $content ...

Edit

Use a function to generate a new variable scope.

function render($script, array $vars = array())
{
    extract($vars);

    ob_start();
    include $script;
    return ob_get_clean();
}

$test = 'one';
echo render('foo.php', array('test' => 'two'));
echo $test; // is still 'one' ... render() has its own scope
Philippe Gerber
Hmm.. how would I inject data then?
Matt
Any number of ways. Do string replaces on $content, make globals available to main.php before including it, the list goes on and on.
Matthew Scharley
I don't think thus would work.. Include would throw errorS before you got a chance to do string replaces.
Matt
A: 

In case you are trying to do this with a string of mixed HTML/PHP (like from a database, as I was), you can do it this way:

eval(' ?>'.$htmlandphp.'<?php ');

More info: http://blog.5ubliminal.com/posts/eval-for-inline-php-inside-html/

Josh L