简体   繁体   中英

PHP stream wrapper error

I'm trying to write a "Identity Stream Wrapper". The first purpose is to make PHP transit through this wrapper which will make exactly the same things that PHP would do by itself. The second is to modify this wrapper to enable decisions making.

So the first work was to map stream_open() to fopen(), stream_write() to fwrite(), and so on. fopen() mapping seems to work fine, but when I try to call fwrite(), the internal resource of the wrapper turns to boolean for some reason, and the file could not be written. The same thing occurs with fread().

Can anyone explain me why and how to avoid/work around ? Thanks...

Here is the output of my script :

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)

Here is its code (not all by enough to reproduce) :

<?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();

?>

The method stream_open has to return a boolean, not a resource as fopen(). That's all to fix the class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM