(PHP 4 >= 4.3.2, PHP 5, PHP 7, PHP 8)
Allows you to implement your own protocol handlers and streams for use with all the other filesystem functions (such asfopen(),fread() etc.).
Note:
This isNOT a real class, only a prototype of how a class defining its own protocol should be.
Note:
Implementing the methods in other ways than described here can lead to undefined behaviour.
An instance of this class is initialized as soon as a stream function tries to access the protocol it is associated with.
The currentcontext, ornull
if no context was passed to the caller function.
Use thestream_context_get_options() to parse the context.
Note:
This propertymust be public so PHP can populate it with the actual context resource.
It's worth noting that the interface defined by yannick at gmail should not always be implemented by a stream wrapper class, as several of the methods should not be implemented if the class has no use for them (as per the manual).
Specifically, mkdir, rename, rmdir, and unlink are methods that "should not be defined" if the wrapper has no use for them. The consequence is that the appropriate error message will not be returned.
If the interface is implemented, you won't have the flexibility to not implement those methods.
Not trying to be academic, but it was useful for me.
THIS METHODS NOT REQUIRED, you can implement only part of their: directories, files, etc.
For example, "glob://" support minimal syntax, glob() more powerful, you can replace/extend native wrapper: check options in tablehttps://www.php.net/manual/ru/wrappers.glob , you need create wrapper only with 'dir_...dir' methods. For more info, seehttps://www.php.net/manual/en/class.globiterator.php#125220
Here is a very simple stream wrapper which calls your callback function for reads:
<?php
classCallbackUrl
{
constWRAPPER_NAME='callback';
public$context;
private$_cb;
private$_eof=false;
private static$_isRegistered=false;
public static functiongetContext($cb)
{
if (!self::$_isRegistered) {
stream_wrapper_register(self::WRAPPER_NAME,get_class());
self::$_isRegistered=true;
}
if (!is_callable($cb)) returnfalse;
returnstream_context_create(array(self::WRAPPER_NAME=> array('cb'=>$cb)));
}
public functionstream_open($path,$mode,$options, &$opened_path)
{
if (!preg_match('/^r[bt]?$/',$mode) || !$this->context) returnfalse;
$opt=stream_context_get_options($this->context);
if (!is_array($opt[self::WRAPPER_NAME]) ||
!isset($opt[self::WRAPPER_NAME]['cb']) ||
!is_callable($opt[self::WRAPPER_NAME]['cb'])) returnfalse;
$this->_cb=$opt[self::WRAPPER_NAME]['cb'];
returntrue;
}
public functionstream_read($count)
{
if ($this->_eof|| !$count) return'';
if (($s=call_user_func($this->_cb,$count)) =='')$this->_eof=true;
return$s;
}
public functionstream_eof()
{
return$this->_eof;
}
}
classTest{
private$_s;
public function__construct($s)
{
$this->_s=$s;
}
public functionread($count) {
returnfread($this->_s,$count);
}
}
$t= newTest(fopen('/etc/services','r'));
$fd=fopen('callback://','r',false,CallbackUrl::getContext(array($t,'read')));
while(($buf=fread($fd,128)) !='') {
print$buf;
}
?>
a php interface for wrapper
<?php
interfaceWrapperInterface
{
/**
* resource context
*
* @var resource
*/
//public $context;
/**
* constructor
*
*/
public function__construct();
/**
*
*
* @return bool
*/
public functiondir_closedir();
/**
* Enter description here...
*
* @param string $path
* @param int $options
* @return bool
*/
public functiondir_opendir($path,$options);
/**
* Enter description here...
*
* @return string
*/
public functiondir_readdir();
/**
* Enter description here...
*
* @return bool
*/
public functiondir_rewinddir();
/**
* Enter description here...
*
* @param string $path
* @param int $mode
* @param int $options
* @return bool
*/
public functionmkdir($path,$mode,$options);
/**
* Enter description here...
*
* @param string $path_from
* @param string $path_to
* @return bool
*/
public functionrename($path_from,$path_to);
/**
* Enter description here...
*
* @param string $path
* @param int $options
* @return bool
*/
public functionrmdir($path,$options);
/**
* Enter description here...
*
* @param int $cast_as
* @return resource
*/
public functionstream_cast($cast_as);
/**
* Enter description here...
*
*/
public functionstream_close();
/**
* Enter description here...
*
* @return bool
*/
public functionstream_eof();
/**
* Enter description here...
*
* @return bool
*/
public functionstream_flush();
/**
* Enter description here...
*
* @param mode $operation
* @return bool
*/
public functionstream_lock($operation);
/**
* Enter description here...
*
* @param string $path
* @param string $mode
* @param int $options
* @param string &$opened_path
* @return bool
*/
public functionstream_open($path,$mode,$options, &$opened_path);
/**
* Enter description here...
*
* @param int $count
* @return string
*/
public functionstream_read($count);
/**
* Enter description here...
*
* @param int $offset
* @param int $whence = SEEK_SET
* @return bool
*/
public functionstream_seek($offset,$whence=SEEK_SET);
/**
* Enter description here...
*
* @param int $option
* @param int $arg1
* @param int $arg2
* @return bool
*/
public functionstream_set_option($option,$arg1,$arg2);
/**
* Enter description here...
*
* @return array
*/
public functionstream_stat();
/**
* Enter description here...
*
* @return int
*/
public functionstream_tell();
/**
* Enter description here...
*
* @param string $data
* @return int
*/
public functionstream_write($data);
/**
* Enter description here...
*
* @param string $path
* @return bool
*/
public functionunlink($path);
/**
* Enter description here...
*
* @param string $path
* @param int $flags
* @return array
*/
public functionurl_stat($path,$flags);
}
?>