miércoles, 25 de junio de 2025

Manipulación Avanzada de Streams con Wrappers Personalizados en PHP

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