9

In PHP, I want to read a file into a variable and process the PHP in the file at the same time without using output buffering. Is this possible?

Essentially I want to be able to accomplish this without using ob_start():

<?php
ob_start();
include 'myfile.php';
$xhtml = ob_get_clean();
?>

Is this possible in PHP?

Update: I want to do some more complex things within an output callback (where output buffering is not allowed).

1
  • Why not just use output buffering? Commented Oct 21, 2008 at 18:29

8 Answers 8

27

A little known feature of PHP is being able to treat an included/required file like a function call, with a return value.

For example:

// myinclude.php
$value = 'foo';
$otherValue = 'bar';
return $value . $otherValue;


// index.php
$output = include './myinclude.php';
echo $output;
// Will echo foobar
Sign up to request clarification or add additional context in comments.

1 Comment

Also pertinent is that variables set in index.php before the include are available and evaluated when you include myinclude.php.
9

From what I can tell in the PHP documentation, no. Why do you want to avoid output buffering?

The only way to get around this would be hacky methods involving either invoking the command line php client or doing a curl request based on what's available and what the particular requirements are.

Comments

5

After reading everybody's suggestions, reading a bunch of documentation, and playing around with some things, I came up with this:

<?php
$file = file_get_contents('/path/to/file.php');
$xhtml = eval("?>$file");
?>

It's as close as I could get but it unfortunately doesn't work. The key to this is to include the closing PHP bit (?>) before the contents of the file. This will take the eval() out of PHP-evaluation mode and will treat the contents of the file starting as non-PHP code. Then if there are PHP code blocks within the file, those will be evaluated as PHP. The bummer is that it doesn't save the eval'd content in the variable, it just outputs it to the page.

Thanks for the help everybody!

2 Comments

And that actually returns the output of the eval'd file? From what I read at us.php.net/manual/en/function.eval.php you'd still need to use output buffering.
@JoeLencioni NO, if you use return "blabla" in file.php, then use echo eval(...) ...............please, edit your answer.
1

Joeri Sebrechts is correct. An equivalent and slightly easier method is available if the PHP script is HTTP accessible:

$data = file_get_contents('http://google.com/');

It should be noted that using output buffering would be easier on resources.

1 Comment

Many servers disable allow_furl_open and this will not be an option.
0

Do a curl request to the php page, essentially pretending to be the browser.

1 Comment

This doesn't work if the file is not publicly accessible. See the answer by Rabbit ... (also file_get_contents is easier than cURL).
0

What you could do, if the file is local, is load the script into a variable as a string, then run eval on the string. Then you can do all your other stuff afterwards. Otherwise, you have to use output buffering.

1 Comment

Unfortunately, that won't work because eval() evaluates PHP code whereas accessing a page will only evaluate the PHP code if it is in a PHP code block (e.g. between <?php and ?>)
0
$fileData = file_get_contents('fileOnDisk.php');
$results = eval($fileData);

But check the documentation on eval, because you actually have to have the file you are calling return its results rather than just echo them:

https://www.php.net/eval

Comments

-1

Hack Alert! You could do the evaluation of the PHP yourself with a bit of hackery using preg_replace_callback to search and replace the PHP blocks.

function evalCallback($matches)
{
    // [0] = <?php return returnOrEcho("hi1");?>
    // [1] = <?php
    // [2] = return returnOrEcho("hi1");
    // [3] = ?>
    return eval($matches[2]);
}

function evalPhp($file)
{
    // Load contents
    $contents = file_get_contents($file);
    // Add returns
    $content_with_returns = str_replace(
                               "returnOrEcho"
                              ,"return returnOrEcho"
                              ,$contents);
    // eval
    $modified_content = preg_replace_callback(
                              array("|(\<\?php)(.*)(\?\>)|"
                             ,"evalCallback"
                             ,$content_with_returns);
    return $modified_content;
}

You would have to modify the PHP file you are including to use a returnOrEcho function so that it can be overloaded for this case and the normal case. In this case you want to return so that it will be picked up by the eval in the way you want, but the normal case is to echo without a return.

So for this case you would define:

function returnOrEcho($str)
{
    return $str;
}

and for the normal case you would define:

function returnOrEcho($str)
{
    echo $str;
}

In your included PHP file (or view file) you would have something like this:

<?php returnOrEcho("hi1");?>
<?php returnOrEcho("hi3"."oo");?>
<?php returnOrEcho(6*7);?>

I couldn't get preg_replace_callback inline callback working so I used a separate function, but there is an example of how to do it: preg_replace_callback() - Calback inside current object instance.

1 Comment

as i see, you have missed one serious thing, and you need to modify that. if in that file, there is several ECHO, then it is ok, but that function replaces ECHOs with RETURNs, so on the first RETURN the script will be ended, instead of continuing it (like it was could have been using ECHO)

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.