Skip to content

Instantly share code, notes, and snippets.

@Radiergummi
Created November 23, 2018 09:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Radiergummi/f3c19e54ee6e06eac4fad2dcd085c897 to your computer and use it in GitHub Desktop.
Save Radiergummi/f3c19e54ee6e06eac4fad2dcd085c897 to your computer and use it in GitHub Desktop.
PHP class that allows to intercept output to a stream, like STDOUT. Very useful for testing CLI applications using `fwrite('', STDOUT);`.
<?php
/**
* Intercepts bytes written to an output stream and redirects them into a buffer instead
*/
class OutputInterceptor extends php_user_filter
{
/**
* Holds the PHP stream filter
*/
protected static $interceptor;
/**
* Holds the output buffer
*/
protected static $buffer = '';
/**
* Reads the captured output and flushes the buffer.
*/
public static function flush(): string
{
$output = static::$buffer;
static::$buffer = '';
return $output;
}
/**
* Starts capturing the output on a stream. This has to be called before writing data.
*/
public static function capture($stream)
{
stream_filter_register('intercept', static::class);
static::$interceptor = stream_filter_append($stream, 'intercept');
}
/**
* Releases the capturing by removing the stream filter. This has to be called after writing data.
*/
public static function release()
{
stream_filter_remove(static::$interceptor);
}
/**
* PHP User Filter handler - this is where the magic happens!
* Replace PSFS_FEED_ME with PSFS_PASS_ON to achieve a "tee" effect, where the output gets written to
* both the output stream as well as the buffer.
*/
public function filter($in, $out, &$consumed, $closing)
{
while ($bucket = stream_bucket_make_writeable($in)) {
static::$buffer .= $bucket->data;
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_FEED_ME;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment