Пример класса, зарегистрированного в качестве обертки потока

Пример ниже реализует обработчик протокола var://, который позволяет читать/писать в именованную глобальную переменную, используя стандартные потоковые функции, работающие с файловой системой, такие как fread(). Протокол var:// при передаче URL "var://foo" будет читать/писать из/в $GLOBALS["foo"].

Пример #1 Поток для чтения/записи глобальных переменных

<?php

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(
"Не удалось зарегистрировать обертку");

$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);

?>

Результат выполнения данного примера:

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

Коментарии

Example of stream used with databases :

Requirement :
A MySQL database with a table named data structured as follow :
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 ;

Now with the stream implementation :

<?php

class DBStream {
    private 
$_pdo;
    private 
$_ps;
    private 
$_rowId 0;

    function 
stream_open($path$mode$options, &$opath)
    {
       
$url parse_url($path);
       
$url['path'] = substr($url['path'], 1);
        try{
           
$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;
    }

    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;
    }

    function 
stream_write($data)
    {
       
$this->_ps->execute(array($data));
        return 
strlen($data);
    }

    function 
stream_tell()
    {
        return 
$this->_rowId;
    }

    function 
stream_eof()
    {
       
$this->_ps->execute(array($this->_rowId));
        return (bool) 
$this->_ps->rowCount();
    }

    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');
//The two forms above are accepted : for the former, the default password "" will be used

$alg hash_algos();
$al $alg[array_rand($alg)];
$data hash($alrand(rand(09), rand(10999))); // Some random data to be written
fwrite($fw$data); // Writing the data to the wrapper
while($a fread($fr256)){ //A loop for reading from the wrapper
   
echo $a '<br />';
}
?>

Hope it helps, cheers ;)
2010-08-08 12:47:22
http://php5.kiev.ua/manual/ru/stream.streamwrapper.example-1.html

    Поддержать сайт на родительском проекте КГБ