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($al, rand(rand(0, 9), rand(10, 999))); // Some random data to be written
fwrite($fw, $data); // Writing the data to the wrapper
while($a = fread($fr, 256)){ //A loop for reading from the wrapper
echo $a . '<br />';
}
?>
Hope it helps, cheers ;)
Ejemplo de clase registrada como envoltura de flujo
El ejemplo de abajo implementa un gestor de protocolo var:// que permite el acceso a la lectura/escritura de una variable global nominada usando un flujo de sistema de archivos estándar tal como fread(). El protocolo var:// implementado abajo, dada la URL "var://foo", leerá/escribirá información hacia/desde $GLOBALS["foo"].
Ejemplo #1 Un Flujo para leer/escribir variables globales
<?php
class FlujoVariable {
var $posición;
var $nombre;
function stream_open($ruta, $modo, $opciones, &$ruta_abierta)
{
$url = parse_url($ruta);
$this->nombre = $url["host"];
$this->posición = 0;
return true;
}
function stream_read($cuenta)
{
$ret = substr($GLOBALS[$this->nombre], $this->posición, $cuenta);
$this->posición += strlen($ret);
return $ret;
}
function stream_write($data)
{
$izquierda = substr($GLOBALS[$this->nombre], 0, $this->posición);
$derecha = substr($GLOBALS[$this->nombre], $this->posición + strlen($data));
$GLOBALS[$this->nombre] = $izquierda . $data . $derecha;
$this->posición += strlen($data);
return strlen($data);
}
function stream_tell()
{
return $this->posición;
}
function stream_eof()
{
return $this->posición >= strlen($GLOBALS[$this->nombre]);
}
function stream_seek($índice, $dónde)
{
switch ($dónde) {
case SEEK_SET:
if ($índice < strlen($GLOBALS[$this->nombre]) && $índice >= 0) {
$this->posición = $índice;
return true;
} else {
return false;
}
break;
case SEEK_CUR:
if ($índice >= 0) {
$this->posición += $índice;
return true;
} else {
return false;
}
break;
case SEEK_END:
if (strlen($GLOBALS[$this->nombre]) + $índice >= 0) {
$this->posición = strlen($GLOBALS[$this->nombre]) + $índice;
return true;
} else {
return false;
}
break;
default:
return false;
}
}
function stream_metadata($ruta, $opción, $var)
{
if($opción== STREAM_META_TOUCH) {
$url = parse_url($ruta);
$varname = $url["host"];
if(!isset($GLOBALS[$varname])) {
$GLOBALS[$varname] = '';
}
return true;
}
return false;
}
}
stream_wrapper_register("var", "FlujoVariable")
or die("Error al registrar el protocolo");
$mivar = "";
$fp = fopen("var://mivar", "r+");
fwrite($fp, "línea1\n");
fwrite($fp, "línea2\n");
fwrite($fp, "línea3\n");
rewind($fp);
while (!feof($fp)) {
echo fgets($fp);
}
fclose($fp);
var_dump($mivar);
?>
El resultado del ejemplo sería:
línea1 línea2 línea3 string(24) "línea1 línea2 línea3 "
pfe dot skh at gmail dot com ¶
2 years ago
