PHP 流包装器错误


PHP stream wrapper error

我正在尝试编写一个"身份流包装器"。第一个目的是使PHP通过这个包装器进行传输,这将产生与PHP自己完全相同的事情。第二种是修改此包装器以启用决策。

所以第一个工作是将stream_open()映射到fopen(),stream_write()映射到fwrite(),等等。 fopen() 映射似乎工作正常,但是当我尝试调用 fwrite() 时,包装器的内部资源由于某种原因变成了布尔值,并且无法写入文件。同样的事情也发生在 fread() 中。

谁能解释我为什么以及如何避免/变通?谢谢。。。

这是我的脚本的输出:

36: resource(6) of type (stream)
60: resource(7) of type (stream)
49: bool(true)
PHP Warning:  fwrite() expects parameter 1 to be resource, boolean given in /var/www/projects/stream/test.php on line 51
PHP Stack trace:
PHP   1. {main}() /var/www/projects/stream/test.php:0
PHP   2. fwrite() /var/www/projects/stream/test.php:62
PHP   3. IdentityStreamWrapper->stream_write() /var/www/projects/stream/test.php:62
PHP   4. fwrite() /var/www/projects/stream/test.php:51
63: resource(7) of type (stream)

这是它的代码(不足以重现):

<?php
class IdentityStreamWrapper {
    var $fileHd;
    var $fileName;
    function __construct() {
      static::unwrap();
    }
    function __destruct() {
      static::wrap();
    }
    static function unwrap() {
        stream_wrapper_restore("file");
    }
    static function wrap() {
        stream_wrapper_unregister("file");
        stream_wrapper_register("file", "IdentityStreamWrapper");   
    }
    function stream_open($path, $mode, $options, &$opened_path)
    {
        if ($options >0) {
          $tOptions = $options;
          $tOptions = ($tOptions > STREAM_USE_PATH) ? ($tOptions - STREAM_REPORT_ERRORS) : $tOptions;
          if ($tOptions === STREAM_USE_PATH) {
            $opened_path = realpath($path);
          }
        }
        $this->fileName = $path;
        $this->fileHd = fopen($path,$mode);
        $this->position = 0;
echo __LINE__.": ";
var_dump($this->fileHd);
        return $this->fileHd;
    }
    function stream_write($data)
    {
echo __LINE__.": ";
var_dump($this->fileHd);
        $ret = fwrite($this->fileHd,$data);
        return $ret;
    }
}
IdentityStreamWrapper::wrap();
$fp = fopen("test.txt", "w+");
echo __LINE__.": ";
var_dump($fp);
fwrite($fp, "line1'n");
echo __LINE__.": ";
var_dump($fp);
IdentityStreamWrapper::unwrap();
?>

方法stream_open必须返回布尔值,而不是 fopen() 资源。这就是修复类的全部内容。