Is there a way to automatically include content before and after the actual output of a file?
Why? For example to use this to include everything up to the main content (dynamcally generated HTML, head, opening tags…) and after the file runs, automatically close everything up again.
I know of the ob_start
approach, but I’m not sure if dynamically generated content is easy to include that way:
<?php
function bootstrap_page($content) {
return "text before" . $content . "text after";
}
ob_start(bootstrap_page);
?>
But then, ob
cannot be used to capture the output of an include within the callback, AFAIK. So that makes it hard to easily pre- and append something dynamically generated. I could use long strings in the callback function to get a static version working – but is there a way to do this more seamlessly?
In other words I’m basically trying to include a php file before and one after any (other) file I need and that – if possible reduced to a function call at the start of a given file.
The functionality I’m looking for would transform this:
<?php
bootstrap_this();
?>
<p>Lorem ipsum</p>
before.php:
<!DOCTYPE html>
<html>
<?php include('head.php'); ?>
<body>
<?php if(somecondition) { ?>
<h1>Hello, World!</h1>
<?php } ?>
after.php:
</body>
</html>
Into something like this:
<?php
include 'before.php';
?>
<p>Lorem ipsum</p>
<?php
include 'after.php';
?>
And in the end into:
<!DOCTYPE html>
<html>
<?php include('head.php'); ?>
<body>
<?php if(somecondition) { ?>
<h1>Hello, World!</h1>
<?php } ?>
<p>Lorem ipsum</p>
</body>
</html>
4
Answers
Thanks to the help of @bestprogrammerintheworld, I came up with this:
If this function is called a the beginning of a php file, the outputs of
before.php
andafter.php
get stored and bound to the callback. Then, after all the main output is read, everything is pieced together. No code at the end of the file required.Since
ob
cannot be run within the callback,bootstrap_page
, it must be run beforehand to capture the other files first.AFAYK ? Would it be hard to test? As long as the include is after ob_start() and the code does not explicitly call ob_flush() before you choose to do so, then it will capture the output.
That implies some set sort of controlling script which calls the pre-oinclude, the main content and the post-include.
That would be OK if HTML (not true, I’ll come back to that) did not have a defined root which should be explicitly declared. And you have the issue HTTP also has a structure which you risk subverting here – headers come before content. But leaving those aside for now, HTML requires a nested structure. All tags should be closed. Opening and closing tags in different files is messy and bad practice.
There are a whole lot technologies which provide the end result you appear to be looking for – ESI, templating and front-controller patterns all provide this in a much more structured way.
I’m not sure I see the usage of this or if I understood this correct, but if I understood it correctly you’re looking for something like this:
Usage:
In before.php and after.php a return would be required, e.g.
and the result would be:
UPDATE:
It seems it more something like this you’re looking for. output-buffers are the only way AFAIK to achieve this.
This code is not optimized at all… (I just show the concept here)
As other stated though – it’s a lot of platforms, frameworks, template engines out there that could solve this issue. You will have do ob_start() and ob_clean within the current files content for this to work.
UPDATE2:
In this case I fetch current files output buffer as content.
Isn’t that what output buffering is for?