Funciones de Flujos
PHP Manual

stream_filter_register

(PHP 5)

stream_filter_registerRegistrar un filtro de flujo definido por el usuario

Descripción

bool stream_filter_register ( string $filtername , string $classname )

stream_filter_register() permite implementar un filtro propio sobre cualquier flujo registrado usado con las demás funciones de sistema de archivos (como fopen(), fread() etc.).

Parámetros

filtername

El nombre del filtro que va a ser registrado.

classname

Para implementar un filtro se necesita definir una clase como una extensión de php_user_filter con un número de funciones miembro como se define abajo. Cuando se lleva a cabo operaciones de lectura/escritura en el flujo al cuál el filtro está enlazado, PHP pasará la información a través de este filtro (y cualquier otro filtro enlazado a ese flujo) por lo que la información puede ser modificada como se desee. Se deben implementar los métodos exactamente como se describe abajo - hacerlo de otro modo conducirá a un comportamiento indefinido.

int filter ( resource $in , resource $out , int &$consumed , bool $closing )

Este método es llamado siempre que la información es leída desde o escrita en el flujo enlazado (como con fread() o fwrite()). in es un recurso que apunta a una cadena de recipientes que contiene uno o más objetos recipiente que contienen la información que va a ser filtrada. out es un recurso que apunta a una segunda cadena de recipientes dentro de la cual se deberían ubicar los recipientes modificados. consumed, el cual siempre debe ser declarado por referencia, debería ser incrementado por la longitud de la información que el filtro lee y altera. En la mayoría de los casos esto significa que se incrementará consumed por $recipiente->datalen por cada $recipiente. Si el flujo está en el proceso de cierre (y por lo tanto éste es el último pase a través de la cadena de filtros), el parámetro closing será establecido a TRUE. El método filter() debe devolver uno de estos tres valores cuando se complete.

Valor Devuelto Significado
PSFS_PASS_ON El filtró se procesó con éxito con información disponible en la cadena de recipientes out.
PSFS_FEED_ME El filtró se procesó con éxito, sin embargo no había información disponible que devolver. Se requiere más información del flujo o del filtro previo.
PSFS_ERR_FATAL (predeterminado) El filtro experimentó un error irrecuperable y no puede continuar.

bool onCreate ( void )
Este método se llama durante la instanciación del objeto de la clase del filtro. Si el filtro asigna o inicializa cualquier otro recurso (como un buffer), éste es el lugar para hacerlo. La implementación de este método debería devolver FALSE en caso de error, o TRUE en caso de éxito. Cuando primero se instancia el filtro, y se llama a elfiltro->onCreate(), estarán disponibles varias propiedades como se muestra en la tabla de abajo.

Propiedad Contenido
FilterClass->filtername Una cadena que contiene el nombre del filtro con el que fue instanciado. Los filtros pueden ser registrados bajo múltiples nombres o bajo comodines. Use esta propiedad para determinar qué nombre fue usado.
FilterClass->params El contenido del parámetro params pasado a stream_filter_append() o a stream_filter_prepend().
FilterClass->stream El recurso de flujo que va a ser filtrado. Quizás disponible sólo durante las llamadas a filter() cuando el parámetro closing es FALSE.

void onClose ( void )

Este método es llamado bajo el cierre del filtro (normalmente también durante el cierre del flujo), y se ejecuta después de llamar al método flush. Si se asignó o inicializo cualquier recurso durante onCreate(), este sería el momento de destruirlo o deshacerse de él.

Valores devueltos

Devuelve TRUE en caso de éxito o FALSE en caso de error.

stream_filter_register() devolverá FALSE si filtername ya está definido.

Ejemplos

Example #1 Filtro para poner en mayúsculas caracteres en el flujo foo-bar.txt

El ejemplo de abajo implementa un filtro llamado strtoupper en el flujo foo-bar.txt que pondrá en mayúsculas todos los caracteres de letras escritos en/leídos desde este flujo.

<?php

/* Definir nuestra clase de filtro */
class strtoupper_filter extends php_user_filter {
  function 
filter($entrada$salida, &$consumido$cerrar)
  {
    while (
$recipiente stream_bucket_make_writeable($entrada)) {
      
$recipiente->data strtoupper($recipiente->data);
      
$consumido += $recipiente->datalen;
      
stream_bucket_append($salida$recipiente);
    }
    return 
PSFS_PASS_ON;
  }
}

/* Registrar nuestro filtro con PHP */
stream_filter_register("strtoupper""strtoupper_filter")
    or die(
"Fallo al registrar el filtro");

$fp fopen("foo-bar.txt""w");

/* Enlazar el filtro al flujo recién abierto */
stream_filter_append($fp"strtoupper");

fwrite($fp"Fila1\n");
fwrite($fp"Palabra - 2\n");
fwrite($fp"Tan Sencillo Como 123\n");

fclose($fp);

/* Leer el contenido desde atrás
 */
readfile("foo-bar.txt");

?>

El resultado del ejemplo sería:

FILA1
PALABRA - 2
TAN SENCILLO COMO 123

Example #2 Registrar una clase de filtro genérica para comparar múltiples nombres de filtro.

<?php

/* Definir nuestra clase de filtro */
class string_filter extends php_user_filter {
  var 
$modo;

  function 
filter($entrada$salida, &$consumido$cerrar)
  {
    while (
$recipiente stream_bucket_make_writeable($entrada)) {
      if (
$this->mode == 1) {
        
$recipiente->data strtoupper($recipiente->data);
      } elseif (
$this->mode == 0) {
        
$recipiente->data strtolower($recipiente->data);
      }

      
$consumido += $recipiente->datalen;
      
stream_bucket_append($salida$recipiente);
    }
    return 
PSFS_PASS_ON;
  }

  function 
onCreate()
  {
    if (
$this->filtername == 'str.toupper') {
      
$this->mode 1;
    } elseif (
$this->filtername == 'str.tolower') {
      
$this->mode 0;
    } else {
      
/* Se preguntó por otro filtro str.*,
         informar del fallo, por lo que PHP seguirá mirando */
      
return false;
    }

    return 
true;
  }
}

/* Registrar nuestro filtro con PHP */
stream_filter_register("str.*""string_filter")
    or die(
"Fallo al registrar el filtro");

$fp fopen("foo-bar.txt""w");

/* Enlazar el filtro al flujo recién abierto
   Alternativamente podríamos enlazar a str.tolower aquí */
stream_filter_append($fp"str.toupper");

fwrite($fp"Fila1\n");
fwrite($fp"Palabra - 2\n");
fwrite($fp"Tan Sencillo Como 123\n");

fclose($fp);

/* Leer el contenido desde atrás
 */
readfile("foo-bar.txt");

?>

El resultado del ejemplo sería:

FILA1
PALABRA - 2
TAN SENCILLO COMO 123

Ver también


Funciones de Flujos
PHP Manual