Ausgabepuffer Wrapperklasse
Output buffering wrapper class
This is a class is for having the output buffer well organized. It is loaded and enabled by
default when you include the swlib main class. In normal operation you do not recognise that
this functionality is included, and it does not prevent you from using the normal ob_something()
functions of PHP.
Diese Klasse organisiert das PHP Output-Buffering etwas übersichtlicher. Die Klasse greift auf meinen Tracer (inklusive dem Interface ITracable) zu, das ist jedoch nicht von zentraler Bedeutung für die Ausgabepufferung. Man kann das Interface und den Aufruf des Tracers auch entfernen ...
Example
Beispiel
<?php
require_once 'swlib/swlib.class.php';
use sw\OutputBuffer;
// Starts the global output buffer. Removed all existing buffers before
// initializing the main buffer.
OutputBuffer::start();
// Returns the actual level of the buffer (= ob_get_level())
$level = OutputBuffer::getLevel();
// Aborts all buffers without sending them. Instead the output is returned
// as string
$all_output = OutputBuffer::purge();
// Disable and send all existing/nested output buffers this function is
// good to be used before exiting a script or closing the connection to
// the client.
OutputBuffer::abort();
// Same as abort();
OutputBuffer::disable();
// This is the use of a buffer in a function context.
function something_buffered_here() {
// Instantiating a new buffer will make a buffer available that is automatically
// deleted when the function returns. You can fetch its output or ignore it.
// The Object saves its creation time level and will remove/return all nested
// buffer contents.
$ob = new OutputBuffer();
print "[...]";
// Fetch output
$output = $ob->getOutput();
// $ob will be destructed here, all not fetched outputs are removed.
}
Class source code
Klassen-Quelltext
<?php
/**
* Enables auto output buffering by calling ob_start() at construction and
* ob_end_flush() on destruction. You can overload the onEnd() method to
* add special processes to the buffered content. It is also possible to
* create instances, e.g. $ob = new OutputBuffer(); print "Something";
* $content = $ob->getContents();
*
* @gpackage de.atwillys.sw.php.swLib
* @author Stefan Wilhelm
* @copyright Stefan Wilhelm, 2005-2010
* @license GPL
* @version 1.0
* @uses Tracer
*/
namespace sw;
class OutputBuffer {
/**
* Main instance
* @staticvar OutputBuffer
*/
private static $instance;
/**
* Defines if buffer is shown or dumped (trashed)
*
* @property bool
*/
private $printRemainingOutput = false;
/**
* Defines the buffer level when the ob was started.
* @property int
*/
private $level = 0;
/**
* The callback function, overload this if you want to modify the buffer.
* This function returns null to indicate that the output buffer callback
* is not used.
* $param string $buffer
* @return string
*/
public function onEnd($buffer='') {
return null;
}
public static final function getLevel() {
return ob_get_level();
}
/**
* Starts output control
* @return void
*/
public static final function start() {
while (@ob_get_level() > 0)
@ob_end_clean();
self::$instance = new self();
Tracer::trace("started");
}
/**
* Aborts all buffers and sents the output
* @return void
*/
public static final function abort() {
while (@ob_get_level() > 0)
@ob_end_flush();
}
/**
* Aborts all buffers without sending it. Instead the output
* is returned as string.
* @return string
*/
public static final function purge() {
$out = '';
while (@ob_get_level() > 0) {
$out .= @ob_get_clean();
}
return $out;
}
/**
* Aborts all buffers and sents the output
* @return void
*/
public static final function disable() {
self::abort();
}
/**
* Execute a PHP code in a level 2++ buffer. Restores buffering to level 1
* @param string $code
* @return string
*/
public static final function executeBuffered($code) {
$exception = null;
$buffer = new self();
try {
$result = eval($code);
} catch (\Exception $e) {
$exception = $e;
$result = "<h1>Block exception thrown</h1><br><pre>$exception</pre>";
}
$result .= $buffer->getOutput();
unset($buffer);
if ($exception != null) {
throw $exception;
} else {
return $result;
}
}
/**
* Controller object construction, starts a new output buffer that will
* be purged/printed (depending on $printRemainingOutput) on object
* destruction.
* @param bool $printRemainingOutput=false
*/
public final function __construct($printRemainingOutput=false) {
$this->printRemainingOutput = (bool) $printRemainingOutput;
if (!is_null($this->onEnd())) {
ob_start(array($this, 'onEnd'));
} else {
ob_start();
}
$this->level = ob_get_level();
Tracer::trace("New buffer, level " . $this->level, 3);
}
/**
* Controller object destruction, flushes and writes all higher buffer
* level outputs than level at construction time.
*/
public final function __destruct() {
$out = '';
if (ob_get_level() > $this->level) {
Tracer::trace("Buffer level(" . ob_get_level() . ", construction level=" . $this->level . ") not ok , flushing ");
while (ob_get_level() > $this->level) {
Tracer::trace("Level now " . ob_get_level());
$out .= ob_get_clean();
}
Tracer::trace("Buffer destructed, level " . $this->level . " actual level " . ob_get_level());
} else {
Tracer::trace("ok, already read level " . $this->level, 3);
}
if ($this->printRemainingOutput)
print $out;
}
/**
* Returns the buffered output text.
* @return string
*/
public final function getOutput() {
if ($this->level != ob_get_level()) {
Tracer::trace("Warning: Actual buffer level (" . ob_get_level() . ") is deeper than this construction level (" . $this->level . ")");
return "[Buffer level not ok]";
} else {
return ob_get_clean();
}
}
}