3v4l.org

run code in 300+ PHP versions simultaneously
<?php class StringStreamWrapper { const PROTOCOL = "stringstream"; private $stringstream; private $position; private $stringlength; public function stream_open($path, $mode, $options, &$opened_path) { $contextOptions = stream_context_get_options($this->context); if (!isset($contextOptions[self::PROTOCOL]['string'])) return false; $this->position = 0; // this is our stream! $this->stringstream = $contextOptions[self::PROTOCOL]['string']; $this->stringlength = strlen($this->stringstream); return true; } public function stream_read($len) { $data = substr($this->stringstream, $this->position, $len); $this->position += strlen($data); return $data; } public function stream_write($data){ $l = strlen($data); $this->stringstream = substr($this->stringstream, 0, $this->position) . $data . substr($this->stringstream, $this->position += $l); $this->stringlength = strlen($this->stringstream); return $l; } public function stream_seek($offset, $whence = SEEK_SET) { if ($whence == SEEK_CUR) { $this->position += $offset; } else if ($whence == SEEK_END) { $this->position = $this->stringlength + $offset; } else { $this->position = $offset; } return true; } public function stream_tell() { return $this->position; } public function stream_eof() { return ($this->position >= $this->stringlength); } public function stream_stat() { return array( 7 => $this->stringlength, 'size' => $this->stringlength, ); } static public function Open($string) { $context = stream_context_create(array(self::PROTOCOL => array('string' => &$string))); return fopen(self::PROTOCOL . "://",'r', false, $context); } } stream_wrapper_register(StringStreamWrapper::PROTOCOL, "StringStreamWrapper"); class replace_nullchar_filter extends php_user_filter { function filter($in, $out, &$consumed, $closing) { while ($bucket = stream_bucket_make_writeable($in)) { $bucket->data = str_replace("\0", "", $bucket->data); $consumed += $bucket->datalen; stream_bucket_append($out, $bucket); } return PSFS_PASS_ON; } } stream_filter_register('replacenullchar', 'replace_nullchar_filter'); ####################################### $testString = 'test'; echo "base64_encode = " . base64_encode($testString).PHP_EOL; ####################################### $stream = fopen('php://memory','r+'); fwrite($stream, $testString); rewind($stream); stream_filter_append($stream, 'convert.base64-encode'); echo "memoryStream 1 = " . stream_get_contents($stream).PHP_EOL; ####################################### $stream = fopen('php://memory','r+'); fwrite($stream, $testString); rewind($stream); stream_filter_append($stream, 'replacenullchar'); stream_filter_append($stream, 'convert.base64-encode'); echo "memoryStream 2 = " . stream_get_contents($stream).PHP_EOL; ####################################### $stream = StringStreamWrapper::Open($testString); stream_filter_append($stream, 'replacenullchar'); stream_filter_append($stream, 'convert.base64-encode'); echo "StringStreamWrapper 1 = " . stream_get_contents($stream).PHP_EOL; ####################################### $stream = StringStreamWrapper::Open($testString); stream_filter_append($stream, 'replacenullchar'); stream_filter_append($stream, 'convert.base64-encode'); echo "StringStreamWrapper 2 = " . stream_get_contents($stream).PHP_EOL;
Output for 8.2.0 - 8.2.18, 8.3.0 - 8.3.4, 8.3.6
Deprecated: Return type of replace_nullchar_filter::filter($in, $out, &$consumed, $closing) should either be compatible with php_user_filter::filter($in, $out, &$consumed, bool $closing): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /in/0W3jg on line 74 base64_encode = dGVzdA== memoryStream 1 = dGVzdA== memoryStream 2 = dGVzdA== Deprecated: Creation of dynamic property StringStreamWrapper::$context is deprecated in /in/0W3jg on line 68 StringStreamWrapper 1 = dGVzdA== Deprecated: Creation of dynamic property StringStreamWrapper::$context is deprecated in /in/0W3jg on line 68 StringStreamWrapper 2 = dGVzdA==
Output for 8.3.5
Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 Deprecated: Return type of replace_nullchar_filter::filter($in, $out, &$consumed, $closing) should either be compatible with php_user_filter::filter($in, $out, &$consumed, bool $closing): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /in/0W3jg on line 74 base64_encode = dGVzdA== memoryStream 1 = dGVzdA== memoryStream 2 = dGVzdA== Deprecated: Creation of dynamic property StringStreamWrapper::$context is deprecated in /in/0W3jg on line 68 StringStreamWrapper 1 = dGVzdA== Deprecated: Creation of dynamic property StringStreamWrapper::$context is deprecated in /in/0W3jg on line 68 StringStreamWrapper 2 = dGVzdA==
Output for 8.1.0 - 8.1.27
Deprecated: Return type of replace_nullchar_filter::filter($in, $out, &$consumed, $closing) should either be compatible with php_user_filter::filter($in, $out, &$consumed, bool $closing): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /in/0W3jg on line 74 base64_encode = dGVzdA== memoryStream 1 = dGVzdA== memoryStream 2 = dGVzdA== StringStreamWrapper 1 = dGVzdA== StringStreamWrapper 2 = dGVzdA==
Output for 7.4.14 - 7.4.33, 8.0.1 - 8.0.30
base64_encode = dGVzdA== memoryStream 1 = dGVzdA== memoryStream 2 = dGVzdA== StringStreamWrapper 1 = dGVzdA== StringStreamWrapper 2 = dGVzdA==
Output for 5.5.21 - 5.5.38, 5.6.5 - 5.6.40, 7.0.0 - 7.0.33, 7.1.0 - 7.1.33, 7.2.0 - 7.2.33, 7.3.0 - 7.3.33, 7.4.0 - 7.4.13, 8.0.0
base64_encode = dGVzdA== memoryStream 1 = dGVzdA== memoryStream 2 = dGVzdA== StringStreamWrapper 1 = dGVz StringStreamWrapper 2 = dGVz
Output for 5.5.0 - 5.5.20, 5.6.0 - 5.6.4
base64_encode = dGVzdA== memoryStream 1 = dGVz memoryStream 2 = dGVz StringStreamWrapper 1 = dGVz StringStreamWrapper 2 = dGVz

preferences:
215.31 ms | 401 KiB | 328 Q