PHP 7.4 中包含/流过滤器发生了什么

What happened to include / stream filters in PHP 7.4

去吧! AOP 框架使用带有 include 语句的流过滤器来执行代理生成。它在 PHP 7.3 中运行良好,但现在在 PHP 7.4 beta 2 发布后它看起来有些变化。

不幸的是,流过滤器的文档很差,所以我无法检查发生了什么。也许更有经验的人会知道。

检查以下示例代码:

// index.php

include __DIR__ . '/SampleFilter.php';
SampleFilter::register();

$uri = 'php://filter/read=sample.filter/resource='. __DIR__ . '/Sample.php';

$content = file_get_contents($uri);

include $uri;
Sample::printIt();
// SampleFilter.php

class SampleFilter extends php_user_filter
{
    public const PHP_FILTER_READ = 'php://filter/read=';
    public const FILTER_IDENTIFIER = 'sample.filter';

    protected $data = '';
    protected static $filterId;

    public static function register(string $filterId = self::FILTER_IDENTIFIER) : void
    {
        if (!empty(self::$filterId)) 
        {
            throw new RuntimeException('Stream filter already registered');
        }

        $result = stream_filter_register($filterId, __CLASS__);
        if ($result === false)
        {
            throw new Exception('Stream filter was not registered');
        }

        self::$filterId = $filterId;
    }

    public static function getId() : string
    {
        if (empty(self::$filterId))
        {
            throw new Exception('Stream filter was not registered');
        }

        return self::$filterId;
    }

    public function filter($in, $out, &$consumed, $closing)
    {
        while ($bucket = stream_bucket_make_writeable($in))
        {
            $this->data .= $bucket->data;
        }

        if ($closing || feof($this->stream))
        {
            $consumed = strlen($this->data);

            echo '<h2>Before</h2><pre>'. htmlentities($this->data) .'</pre>';
            $this->data = str_replace('text', 'text!!!!!!!!', $this->data);
            echo '<h2>After</h2><pre>'. htmlentities($this->data) .'</pre>';

            $bucket = stream_bucket_new($this->stream, $this->data);
            stream_bucket_append($out, $bucket);

            return PSFS_PASS_ON;
        }

        return PSFS_FEED_ME;
    }

}
// Sample.php

class Sample
{

    public static function printIt()
    {
        echo 'text';
    }

}

如您所见,$content 已正确修改代码(完整)。 但是在包含该文件时,它看起来像代码被条带化为原始文件长度。 PHP 打印错误:Parse error: syntax error, unexpected end of file in /(...)/Sample.php on line 9

第 9 行超过原始文件大小。

这是 bug,在 PHP7.4 中介绍。已在最新版本修复。