16

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!

5 Answers 5

41

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/ (note this is a dead link as of 2014-3-3)

Sign up to request clarification or add additional context in comments.

1 Comment

18

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!

2 Comments

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.
ob_start()... Wow! Everyday something new! I love StackOverlow! I loooove php! Such a powerful language...
4

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

3 Comments

Hmm.. how would I inject data then?
Any number of ways. Do string replaces on $content, make globals available to main.php before including it, the list goes on and on.
I don't think thus would work.. Include would throw errorS before you got a chance to do string replaces.
1

The best solution in your case is to combine eval and output buffer

// read template into $contents
// replace {title} etc. in $contents
$contents = str_replace("{title}", $title, $contents);
ob_start();
    eval(" ?>".$contents."<?php ");
$html .= ob_get_clean();
echo html;

Comments

0
$contents = htmlentities($contents);
echo html_entity_decode(eval($contents));

1 Comment

To improve the quality of your answer, please include how/why your post will solve the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.