Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example: Decode an Input Stream with PHP filters
<?php
/**
* Example: Decode an Input Stream with PHP filters
*
* decode-input-stream-example.php
*
* @link https://gist.github.com/hakre/d34239bb237c50e728fd
* @link http://stackoverflow.com/q/25051578/367456
*/
# given a file which contains hex-encoded binary sequences that are partially disruped by US-ASCII
# control characters
$transport = '<?xml version=\x221.0\x22 encoding=\x22UTF-8\x22?>
\x0A<issues>\x0A\x09<issue id=\x225863\x22 found=\x221\x22>\xD0\x9F\xD0\xBE \xD0\xBD\xD0\xBE\xD0\xBC\xD0\xB5\xD1\x80\xD1\x83 \xD1\x81\xD1\x87\xD0\xB
5\xD1\x82\xD0\xB0 19479 \xD0\xBD\xD0\xB0\xD0\xB9\xD0\xB4\xD0\xB5\xD0\xBD\xD0\xBE:\x0A\xD0\x97\xD0\xB0\xD0\xBA\xD0\xB0\xD0\xB7 \xD0\xBF\xD0\xBE\xD0\xBA\xD1\x83\xD0\xBF\xD0\xB0\xD1\x82\xD0\xB5\xD0\xBB\xD1\x8F
0000015597 \xD0\xBE...</issue></issues>';
$file = 'data://text/plain;base64,' . base64_encode($transport);
# registering two filters, one to remove control characters, the other to decode hex-sequences
stream_filter_register('filter.controlchars', 'ControlCharsFilter');
stream_filter_register('decode.hexsequences', 'HexDecodeFilter');
# allows to chain those filters and to obtain the decoded (raw) data on-the-fly
$filters = 'filter.controlchars/decode.hexsequences';
$xml = simplexml_load_file("php://filter/read=$filters/resource=" . $file);
echo "issue id: ", $xml->issue['id'], "\n";
$xml->asXML('php://stdout');
/**
* Class ReadFilter
*/
abstract class ReadFilter extends php_user_filter {
function filter($in, $out, &$consumed, $closing) {
while ($bucket = stream_bucket_make_writeable($in)) {
$bucket->data = $this->apply($bucket->data);
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
abstract function apply($string);
}
/**
* Class ControlCharsFilter
*/
class ControlCharsFilter extends ReadFilter {
function apply($string) {
return preg_replace('~[\x00-\x1f]+~', '', $string);
}
}
/**
* Class HexDecodeFilter
*/
class HexDecodeFilter extends ReadFilter {
function apply($string) {
return preg_replace_callback(
'/\\\\x([A-F0-9]{2})/i', 'self::decodeHexMatches'
, $string
);
}
private static function decodeHexMatches($matches) {
return hex2bin($matches[1]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment