百科狗-知识改变命运!
--

stream_wrapper_register() - php 流数据函数stream

梵高1年前 (2023-11-21)阅读数 17#技术干货
文章标签协议

stream_wrapper_register()

(PHP 4 >= 4.3.2, PHP 5, PHP 7)

注册一个用 PHP 类实现的 URL 封装协议

说明

stream_wrapper_register(string $protocol,string $classname[,int $flags= 0]): bool

允许用户实现自定义的协议处理器和流,用于所有其它的文件系统函数中(例如fopen(),fread()等)。

参数

$protocol

待注册的封装的名字。

$classname

实现了$protocol的类名。

$flags

Should be set toSTREAM_IS_URLif$protocolis a URL protocol. Default is 0, local stream.

返回值

成功时返回TRUE,或者在失败时返回FALSE

当$protocol已经有处理者时,stream_wrapper_register()将返回FALSE

更新日志

版本说明
5.2.4添加$flags参数.

范例

stream_wrapper_register() - php 流数据函数stream

如何注册一个 stream wrapper

以上例程会输出:

line1
line2
line3
string(18) "line1
line2
line3
"

参见

  • ThestreamWrapperprototype class
  • Example class registered as stream wrapper
  • stream_wrapper_unregister()Unregister a URL wrapper
  • stream_wrapper_restore()Restores a previously unregistered built-in wrapper
  • stream_get_wrappers() 获取已注册的流类型
If you plan to use your wrapper in a require_once you need to define stream_stat(). If you plan to allow any other tests like is_file()/is_dir(), you have to define url_stat().
stream_stat() must define the size of the file, or it will never be included. url_stat() must define mode, or is_file()/is_dir()/is_executable(), and any of those functions affected by clearstatcache() simply won't work.
It's not documented, but directories must be a mode like 040777 (octal), and files a mode like 0100666. If you wish the file to be executable, use 7s instead of 6s. The last 3 digits are exactly the same thing as what you pass to chmod. 040000 defines a directory, and 0100000 defines a file. It would be really helpful to add this to the official manual!
Updated for PHP 5, and optimized for readability, low line count, and minimum memory use: 
In response to Anonymouse at Coward dot com:
The manual says "Reading stops when up to length bytes have been read, [...] or (after opening userspace stream) when 8192 bytes have been read whichever comes first."
I tested it and fread($filehandle, 4096) returns 4096 bytes, so it's working as the manual says it should. You're right when you say "8192 bytes is always passed to stream_read as count", but that doesn't mean fread will return 8192 bytes. If you call fread twice with length 4096, PHP calls stream_read passing 8192 as count on the first fread, and doesn't call it on second fread. On both cases, fread returns the correct amount of bytes. 
Actually, I don't know if there's a better way to figure out if stream_read() was called by fgets() or e.g. fread() than this one:
  public function stream_read($count)
  {
    $bt = debug_backtrace();
    if(($bt[0]['function'] == 'stream_read') &&
      ($bt[1]['function'] == 'fgets'))
    {
        $pos = strpos($GLOBALS[$this->varname], "\n", $this->position);
        $retval = substr($GLOBALS[$this->varname], $this->position, ($pos > $count) ? $count : $pos+1);
    }
    else
    {
        $retval = substr($GLOBALS[$this->varname], $this->position, $count);
    }
        $this->position += strlen($retval);
        return (string)$retval;
  }
on using dir_opendir on PHP5 make sure you not return a resource object on success. A resource object is diferent from false but php make a cast to bool to dir_opendir return value and modify the value of your resource to 1. 
example:
class myclass{
 private $mysqlHandler;
 public function dir_opendir(....)
 {
  $this->mysqlHandler = mysql_connect(....);
  return $this->mysqlHandler; //this is wrong, next
                     //time you use 
                     //$this->mysqlHandler
                     // the value is 1
 }
}
Updated. I figured there's no need to store the variable name if we're dereferenceing; we can just store the pointer and not have to dereference in each function for brevity.
Also, I added the assertion that the stream is a string, since we're behaving basically like it has to be, and I changed the name to GlobalStream and global://, as that's a more descriptive moniker than VariableName/var://. 
Be aware that even when stream_wrapper_register won't fail, open_basedir will affect functionality of the class.
"for use with all the other filesystem functions"
"all" is not accurate. Unfortunately, zip_open(), and presumably others, will ignore your custom stream wrapper.
In case someone else starts scratching their head like I was, you should change the VariableStream::stream_eof() function to something like this:
  function stream_eof()
  {
    $eof = ($this->position >= strlen($GLOBALS[$this->varname]));
    if(version_compare(PHP_VERSION,'5.0','>=') && version_compare(PHP_VERSION,'5.1','

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)