ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
**stream_wrapper_register** ( string **$protocol** , string **$classname** [, int **$flags** = 0 ] ) : bool 允许用户实现自定义的协议处理器和流,用于所有其它的文件系统函数中(例如 fopen(),fread() 等) 成功时返回 **`TRUE`**, 或者在失败时返回 **`FALSE`**(当`protocol`已经有处理者时,将返回 **`FALSE`** ) **参数** * protocol:待注册的封装的协议名字。 * classname:实现待注册的协议的类名。 * flags:如果协议是URL协议,则应设置为STREAM_IS_URL。 默认值为0,表示本地流。 别名:stream_register_wrapper ~~~ <?php //自定义的包装器类,此外php还提供了一个streamWrapper类 class VariableStream { var $position; var $varname; function stream_open($path, $mode, $options, &$opened_path) { $url = parse_url($path); $this->varname = $url["host"]; $this->position = 0; return true; } function stream_read($count) { $ret = substr($GLOBALS[$this->varname], $this->position, $count); $this->position += strlen($ret); return $ret; } function stream_write($data) { $left = substr($GLOBALS[$this->varname], 0, $this->position); $right = substr($GLOBALS[$this->varname], $this->position + strlen($data)); $GLOBALS[$this->varname] = $left . $data . $right; $this->position += strlen($data); return strlen($data); } function stream_tell() { return $this->position; } function stream_eof() { return $this->position >= strlen($GLOBALS[$this->varname]); } function stream_seek($offset, $whence) { switch ($whence) { case SEEK_SET: if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) { $this->position = $offset; return true; } else { return false; } break; case SEEK_CUR: if ($offset >= 0) { $this->position += $offset; return true; } else { return false; } break; case SEEK_END: if (strlen($GLOBALS[$this->varname]) + $offset >= 0) { $this->position = strlen($GLOBALS[$this->varname]) + $offset; return true; } else { return false; } break; default: return false; } } function stream_metadata($path, $option, $var) { if($option == STREAM_META_TOUCH) { $url = parse_url($path); $varname = $url["host"]; if(!isset($GLOBALS[$varname])) { $GLOBALS[$varname] = ''; } return true; } return false; } } stream_wrapper_register("var", "VariableStream") or die("Failed to register protocol"); $myvar = ""; $fp = fopen("var://myvar", "r+"); fwrite($fp, "line1\n"); fwrite($fp, "line2\n"); fwrite($fp, "line3\n"); rewind($fp); while (!feof($fp)) { echo fgets($fp); } fclose($fp); var_dump($myvar); ~~~ 与数据库一起使用的流示例 ~~~ //sql数据 : CREATE TABLE IF NOT EXISTS `data` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` varchar(255) NOT NULL, `when_inserted` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; //现在使用流实现 class DBStream { private $_pdo; private $_ps; private $_rowId = 0; //实现用fopen等函数打开时执行的代码 fopen ( string $filename , string $mode [, bool $use_include_path = false [, resource $context ]] ) : resource function stream_open($path, $mode, $options, &$opath) { //解析url并提取解析后数组里的path键的值 $url = parse_url($path); $url['path'] = substr($url['path'], 1); try{ //new PDO("mysql:host=localhost;dbname=dbname", $user, $pass) $this->_pdo = new PDO("mysql:host={$url['host']};dbname={$url['path']}", $url['user'], isset($url['pass'])? $url['pass'] : '', array()); } catch(PDOException $e){ return false; } switch ($mode){ case 'w' : $this->_ps = $this->_pdo->prepare('INSERT INTO data VALUES(null, ?, NOW())'); break; case 'r' : $this->_ps = $this->_pdo->prepare('SELECT id, data FROM data WHERE id > ? LIMIT 1'); break; default : return false; } return true; } //实现用fread等函数操作数据时执行的代码 function stream_read() { $this->_ps->execute(array($this->_rowId)); if($this->_ps->rowCount() == 0) return false; $this->_ps->bindcolumn(1, $this->_rowId); $this->_ps->bindcolumn(2, $ret); $this->_ps->fetch(); return $ret; } //实现用fwrite,fputs等函数操作数据时执行的代码 function stream_write($data) { $this->_ps->execute(array($data)); return strlen($data); } //检索流的当前位置 function stream_tell() { return $this->_rowId; } //测试文件指针是否到了文件结束的位置使用feof等函数操作数据时执行的代码 function stream_eof() { $this->_ps->execute(array($this->_rowId)); return (bool) $this->_ps->rowCount(); } //查找流中的特定位置使用fseek等函数操作数据时执行的代码 function stream_seek($offset, $step) { //No need to be implemented } } stream_register_wrapper('db', 'DBStream'); $fr = fopen('db://testuser@localhost/testdb', 'r'); $fw = fopen('db://testuser:testpassword@localhost/testdb', 'w'); //可以接受上述两种形式:对于前者,将使用默认密码“” $alg = hash_algos();//返回已注册的哈希算法列表 $al = $alg[array_rand($alg)];//随机取出数组中的一个加密算法 $data = hash($al, rand(rand(0, 9), rand(10, 999))); // 要写入的一些随机数据 fwrite($fw, $data); // 将数据写入包装器 while($a = fread($fr, 256)){ //从包装器循环的读取数据 echo $a . '<br />'; } ~~~