Forum Moderators: coopster

Message Too Old, No Replies

eval, file_get_contents, and output buffering

Using output buffering to add a site-wide menu

         

ccity

1:45 am on Jul 20, 2005 (gmt 0)

10+ Year Member



I desperately need some help. Let me try to explain...

I want to start output buffering, modify the buffer by adding a php file, then flush the buffer.

Here is my auto_prepend:


<?
function output_buffer($output) {
$site_menu = file_get_contents('site_menu.php',1);
$output = eregi_replace("<body>", "<body>".$site_menu, $output);
return $output;
}
ob_start(output_buffer);
?>

Here is my auto_append:


<?php ob_end_flush();?>

If site_menu.php is only HTML, it works fine. But if site_menu.php includes PHP and HTML, then the PHP code is not parsed since file_get_contents is accessing a local path. Now if I change this line:


$site_menu = file_get_contents('site_menu.php',1);

... to this:

$site_menu = file_get_contents('http:www.domain.com/includes/site_menu.php');

... it *does* work the way I want it too -- it parses the PHP. The problem is the extra processing time required to make an HTTP request versus simply accessing the local file. On my server, it took an extra 0.1 seconds per HTTP request. While this may not sound like much, I actually want to make 12 to 20 changes to the output buffer by replacing text with php files. This would increase download time by 1.2 to 2 seconds, which is simply not acceptable.

I then decided to create a test file with the following contents:


<?
$string = eval('?'.'>'.file_get_contents('site_menu.php',1).'<'.'?');
echo $string;
?>

This worked great. It loaded the raw PHP file, parsed it with eval, and put the result into $string and output it, exactly the way I wanted it to.

So next I tried replacing the $site_menu line with:


$site_menu = eval('?'.'>'.file_get_contents('site_menu.php',1).'<'.'?');

Here's where I'm confused. $site_head is empty after executing this line. The eregi_replace does nothing, since $site_head is empty. Even though it worked fine in the test file, it does not work in this one.

I'm baffled by this.

I'm wondering if it is because the output is being buffered, where as it was not in the test file.

Any thoughts?

jaski

4:44 am on Jul 20, 2005 (gmt 0)

10+ Year Member



I am not sure if I followed your problem right.

But it seems to me that you are doing some thing simple in a complicated way.

You can usually use

include('site_menu.php');

and you can include it after <body> tag as well.

<html>
<body>
<?php include('site_menu.php');?>
.... rest of the things ...

</body>
</html>

ccity

5:08 am on Jul 20, 2005 (gmt 0)

10+ Year Member



LOL... Ya, I guess I didn't explain well. This is all pretty new to me so I'm sorry about that.

I realize that I can simply put an include in the HTML file itself.

My goal, however, is to include a menu and other stuff in the display of HTML files without actually changing the HTML files themselves.

For example, let's say I have a file called test.html:


<html>
<head>
<title>Test</title>
</head>
<body>
Test Message
</body>
</html>

What I'd like to do is insert a menu immediately after <body> when test.html is viewed in a browser without changing test.html.

Right now, I do that by auto-prepending a php script that captures the output of test.html to a buffer, modifies that buffer, then releases the modified buffer to the browser.

Does that make sense?

grandpa

6:10 am on Jul 20, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Would using a different PHP wrapper help? Maybe something along the lines of:

$site_menu = readfile(\"php://filter/resource=http://www.example.com/site_menu.php\");

Reference: Appendix L. List of Supported Protocols/Wrappers [us3.php.net]

coopster

1:31 pm on Jul 20, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member




Here's where I'm confused. $site_head is empty after executing this line.

Where did $site_head come from? It was $site_menu before ...?

ccity

1:52 pm on Jul 20, 2005 (gmt 0)

10+ Year Member



While it doesn't answer my question about eval, I finally came up with a solution that works quite well.

Here's the meat of it:

AUTO_PREPEND


<?
ob_start();
include 'site_menu.php';
$site_menu = ob_get_contents();
ob_end_clean();
ob_start();
?>

AUTO_APPEND


<?
$output = ob_get_contents();
ob_end_clean();
$output = eregi_replace("<body([^>]*)>", "<body".'\1'.">".$site_menu, $output);
echo $output;
?>

In the auto_prepend, I buffer the include so I can then store it in the variable $site_menu. I then clean out the buffer without sending it to the browser, then start buffering again. The HTML file is then buffered and stored in another variable, $output. Again, the buffer is cleaned out without sending it to the brwoser. I then modify $output to add the $site_menu right after <body>. Finally I echo $output (the whole, modified document) to the browser.

Thank you for taking the time to try to help!