Manipulación Avanzada de Streams con Wrappers Personalizados en PHP
En PHP, los streams proveen una forma consistente de interactuar con datos, ya sea desde un archivo, una red, o incluso una cadena de texto. Pero la verdadera potencia de los streams se revela cuando creamos wrappers personalizados. Estos wrappers nos permiten interceptar y modificar el flujo de datos, habilitando funcionalidades complejas como la encriptación/desencriptación transparente, la compresión/descompresión sobre la marcha, o el filtrado de datos en tiempo real.
<?php
class Rot13Stream {
private $fp;
private $mode;
public function stream_open(string $path, string $mode, int $options, string &$opened_path): bool
{
$url = parse_url($path);
$this->fp = fopen($url["scheme"], $mode);
$this->mode = $mode;
if (!$this->fp) {
return false;
}
return true;
}
public function stream_read(int $count): string
{
$data = fread($this->fp, $count);
return str_rot13($data); // Encripta con ROT13 al leer.
}
public function stream_write(string $data): int
{
$data_encoded = str_rot13($data); // Encripta con ROT13 al escribir.
return fwrite($this->fp, $data_encoded);
}
public function stream_close(): void
{
fclose($this->fp);
}
public function stream_eof(): bool
{
return feof($this->fp);
}
}
stream_wrapper_register("rot13", "Rot13Stream");
// Ejemplo de uso:
$path = "rot13://data.txt"; // data.txt existe y tiene contenido en texto plano.
// Escribir datos encriptados con ROT13
file_put_contents($path, "Este es un mensaje secreto!");
// Leer datos desencriptados con ROT13
$secretMessage = file_get_contents($path);
echo "Mensaje secreto: " . $secretMessage . PHP_EOL; // Imprimirá "Rgr vf ha zrafntr frperg!"
?>
El ejemplo anterior demuestra la creación de un wrapper que aplica la codificación ROT13 a los datos que se leen o escriben. La función `stream_wrapper_register` registra el wrapper, asociando el protocolo "rot13" con la clase `Rot13Stream`. Luego, al usar `rot13://data.txt`, PHP utilizará nuestro wrapper personalizado para manipular los datos, encriptándolos al escribir y desencriptándolos al leer. Es crucial implementar correctamente las funciones `stream_open`, `stream_read`, `stream_write`, `stream_close` y `stream_eof` para que el wrapper funcione correctamente.
Este tipo de wrappers pueden ser extendidos para implementar algoritmos de encriptación más robustos, compresión con gzip o bzip2, o incluso para acceder a APIs web de manera transparente, convirtiendo una solicitud HTTP en una operación de lectura/escritura.
<?php
// Ejemplo de un wrapper que simplemente registra la actividad
class LoggingStream {
private $fp;
public function stream_open(string $path, string $mode, int $options, string &$opened_path): bool {
$this->fp = fopen(substr($path, 9), $mode); // Quitamos el prefijo "log://"
error_log("Stream abierto: " . $path . " en modo " . $mode);
return (bool) $this->fp;
}
public function stream_read(int $count): string {
$data = fread($this->fp, $count);
error_log("Stream leido: " . strlen($data) . " bytes");
return $data;
}
public function stream_write(string $data): int {
$bytes = fwrite($this->fp, $data);
error_log("Stream escrito: " . $bytes . " bytes");
return $bytes;
}
public function stream_close(): void {
fclose($this->fp);
error_log("Stream cerrado.");
}
}
stream_wrapper_register("log", "LoggingStream");
// Usar el wrapper de logging:
$file = "log://realfile.txt";
$handle = fopen($file, 'w');
fwrite($handle, "Esto sera registrado.");
fclose($handle);
?>
En resumen, los wrappers personalizados de streams en PHP ofrecen una manera poderosa y flexible de manipular el flujo de datos. Permiten abstraer la complejidad de operaciones de E/S y aplicar transformaciones personalizadas de manera transparente. Su uso adecuado puede simplificar el código, mejorar la seguridad y extender las capacidades de la aplicación.
No hay comentarios:
Publicar un comentario