Shared memory file in PHP

后端 未结 2 2059
走了就别回头了
走了就别回头了 2021-02-04 13:42

I use openssl_pkcs7_sign and openssl_pkcs7_encrypt to create encrypted data. The functions only accept file names. I would like to store the temporary

2条回答
  •  离开以前
    2021-02-04 14:18

    Ok, so the way I would suggest doing this is with a file stream wrapper. Let me whip up a quick example:

    class staticStreamWrapper {
        public $context;
        protected static $data = array();
    
        protected $path    = '';
        protected $pointer = 0;
        protected $writable = false;
    
        public function stream_close() {}
    
        public function stream_eof() {
            return $this->pointer >= strlen(static::$data[$this->path]);
        }
    
        public function stream_flush() {}
    
        public function stream_open($path, $mode, $options, &$opened_path) {
            switch ($mode[0]) {
                case 'r':
                    if (!isset(static::$data[$path])) return false;
                    $this->path = $path;
                    $this->writable = isset($mode[1]) && $mode[1] == '+';
                    break;
                case 'w':
                    static::$data[$path] = '';
                    $this->path = $path;
                    $this->writable = true;
                    break;
                case 'a':
                    if (!isset(static::$data[$path])) static::$data[$path] = '';
                    $this->path = $path;
                    $this->writable = true;
                    $this->pointer = strlen(static::$data[$path]);
                    break;
                case 'x':
                    if (isset(static::$data[$path])) return false;
                    $this->path = $path;
                    $this->writable = true;
                    break;
                case 'c':
                    if (!isset(static::$data[$path])) static::$data[$path] = '';
                    $this->path = $path;
                    $this->writable = true;
                    break;
                default:
                    return false;
            }
            $opened_path = $this->path;
            return true;
        }
    
        public function stream_read($count) {
            $bytes = min(strlen(static::$data[$this->path]) - $this->pointer, $count);
            $data = substr(static::$data[$this->path], $this->pointer, $bytes);
            $this->pointer += $bytes;
            return $data;
        }
    
        public function stream_seek($offset, $whence = SEEK_SET) {
            $len = strlen(static::$data[$this->path]);
            switch ($whence) {
                case SEEK_SET:
                    if ($offset <= $len) {
                        $this->pointer = $offset;
                        return true;
                    }
                    break;
                case SEEK_CUR:
                    if ($this->pointer + $offset <= $len) {
                        $this->pointer += $offset;
                        return true;
                    }
                    break;
                case SEEK_END:
                    if ($len + $offset <= $len) {
                        $this->pointer = $len + $offset;
                        return true;
                    }
                    break;
            }
            return false;
        }
    
        public function stream_stat() {
            $size = strlen(static::$data[$this->path]);
            $time = time();
            return array(
                0 => 0,
                'dev' => 0,
                1 => 0,
                'ino' => 0,
                2 => 0777,
                'mode' => 0777,
                3 => 1,
                'nlink' => 1,
                4 => 0,
                'uid' => 0,
                5 => 0,
                'gid' => 0,
                6 => '',
                'rdev' => '',
                7 => $size,
                'size' => $size,
                8 => $time,
                'atime' => $time,
                9 => $time,
                'mtime' => $time,
                10 => $time,
                'ctime' => $time,
                11 => -1,
                'blksize' => -1,
                12 => -1,
                'blocks' => -1,
            );
        }
    
        public function stream_tell() {
            return $this->pointer;
        }
    
        public function stream_write($data) {
            if (!$this->writable) return 0;
            $size = strlen($data);
            $len = strlen(static::$data[$this->path]);
            if ($this->stream_eof()) {
                static::$data[$this->path] .= $data;
            } else {
                static::$data[$this->path] = substr_replace(
                    static::$data[$this->path],
                    $data,
                    $this->pointer
                );
            }
            $this->pointer += $size;
            return $size;
        }
    
        public function unlink($path) {
            if (isset(static::$data[$path])) {
                unset(static::$data[$path]);
            }
            return true;
        }
    
    }
    

    Now, you would then need to register the wrapper:

    stream_wrapper_register('static', 'staticStreamWrapper');
    

    So you now can treat it like a file even though it never actually leaves PHP (it's stored as a static variable)!

    file_put_contents('static://foo.txt', 'this is my data');
    file_get_contents('static://foo.txt'); // "this is my data"
    $f = fopen('static://foo.txt', 'r'); // should return a resource
    // etc...
    

提交回复
热议问题