Skip to content

6 streams en php

@intelguasoft edited this page Jan 22, 2020 · 1 revision

Curso Master PHP

Streams (?)

Indice de contenido

    1. ¿Qué es un stream?
    1. Stream Contexts
    1. Stream metadata
    1. Stream filters
    1. Stream transports

1. ¿Qué es un stream?

Un stream es un objeto de tipo resource que puede ser leído o escrito de una forma lineal, y con el que se puede usar la función fseek() para buscar posiciones dentro del mismo. Los streams sirven para generalizar operaciones que comparten una funcionalidad común. Son una característica de PHP que fue introducida en PHP 4.3 para unificar los métodos de trabajar con archivos, sockets y otros recursos similares.

Ejemplos de streams: un archivo en el disco duro, una conexión HTTP a un sitio web, una conexión UDP a un servidor, un archivo ZIP, un tunel SSH.

Las operaciones comunes a todos los ejemplos anteriores es que comparten la habilidad de poder ser leídos y escritos. El poder de los streams en PHP es que puedes acceder a todos ellos usando el mismo conjunto de funciones, y si quieres emplear streams en algo, puedes crear tu propio stream wrapper.

Un wrapper o envoltura es un código adicional que le indica al stream cómo manejar protocolos o codificaciones específicas. Por ejemplo, el wrapper** http** permite acceso de lectura a archivos y recursos mediante HTTP utilizando GET, pudiendo traducir así una URL. Puedes ver el listado completo de wrappers en PHP aquí.

Un stream está descrito por un esquema (scheme) y un objetivo (target): scheme://target. El scheme es el nombre del wrapper que se va a usar (file, http, https, ftp, ftps, php...). Si no se especifica una se usa la función predeterminada, que suele ser file://. El target depende del wrapper usado. Para streams relacionados con el sistema de archivos (filesystem), normalmente es una ruta y un nombre de archivo. Para streams relacionados con redes, normalmente es un nombre de host, y con frecuencia con una ruta añadida al final.

Para usar streams, hay que llamar a una función PHP que los utilice. Ejemplos de funciones que soportan streams son fopen(), file_get_contents(), o file(). Si has empleado algunas de estas funciones alguna vez, es que has estado utilizando streams. PHP abre conexiones para el manejo de archivos o para abrir conexiones de redes externas mediante fopen() porque trata todas las fuentes de datos como streams. Es posible crear un stream handler para trabajar con nuevos protocolos y luego poder manejarlos con funciones como fopen() y file_get_contents().

En el caso del wrapper file://, usamos un stream cada vez que accedemos al sistema de archivos. Al utilizar, por ejemplo, readfile(), podemos hacerlo así readfile('/directorio/archivo.txt') o así readfile('file:///directorio/archivo.txt'). Si indicamos una URL readfile('http://google.com'), PHP utilizará el wrapper http. Si se quiere trabajar con un stream concreto, se debe especificar en el URI wrapper://, seguido de lo que se quiera abrir. Por ejemplo:

echo file_get_contents("http://www.ejemplo.com");

Como hemos especificado http:// que hace referencia a sitios web, añadiremos el resto de la URL. Otros ejemplos:

zip:///directorio/carpeta/archivo.zip
file:///directorio/carpeta/archivo.txt
ftp://user:password@ejemplo.com/archivo.txt
ssh2.tunnel://user:password@ejemplo.com:22/192.168.0.1:15

2. Stream Contexts

Un context es un conjunto de opciones o parámetros para streams que modifican y mejoran el funcionamiento de un wrapper. Un uso habitual de un context es modificar el wrapper HTTP, lo que nos evita tener que usar cURL para operaciones simples de red.

Ejemplo:

echo file_get_contents('http://www.ejemplo.com');

Hemos proporcionado la URL pero no hay un mecanismo para enviar otros headers HTTP. Los stream contexts permiten añadir opciones adicionales.

Un context se crea con la función stream_context_create() y se pueden pasar a la mayoría de las funciones de creación de streams relacionados con sistemas de archivos (fopen(), file(), file_get_contents()...).

string file_get_contents ( string $filename [, int $flags = 0 [, resource $context [, int $offset = -1 [, int $maxlen = -1 ]]]] )

Vamos a pasar un array de opciones a la función stream_context_create():

$opciones = array(
    'http' => array(
        'method' => "GET",
        'header' => "Cookie: foo=bar\r\n"
    ));
$context = stream_context_create($opciones);
// Ahora podemos usar el context:
echo file_get_contents("http://www.example.com", 0, $context);
// Para ver las opciones del context:
var_dump(stream_context_get_options($context));
/*
 Devuelve:
array (size=1)
  'http' =>
    array (size=2)
      'method' => string 'GET' (length=3)
      'header' => string 'Cookie: foo=bar
' (length=38)
 */

Existen otras funciones básicas más en la utilización de contexts:

  • stream_context_set_option
bool stream_context_set_option (resource $stream_or_context, string $wrapper, string $option, mixed $value)

o escrita utilizando un array (que es como se pasarán las opciones normalmente):

bool stream_context_set_option (resource $stream_or_context, array $options)

Permite establecer opciones en el context especificado. Siguiendo el ejemplo anterior:

$nuevosHeaders = array('http'=> array(
    'header' =>
        "Content-Type: application/x-www-form-urlencode\r\n" .
        "Cookie: foo=bar\r\n"
));
stream_context_set_option($context, $nuevosHeaders);
var_dump(stream_context_get_options($context));
/*
array (size=1)
  'http' =>
    array (size=2)
      'method' => string 'GET' (length=3)
      'header' => string 'Content-Type: application/x-www-form-urlencode
Cookie: foo=bar
' (length=86)
 */
  • stream_context_set_params
bool stream_context_set_params (resource $stream_or_context, array $params)

Permite establecer parámetros en el contexto especificado (también permite establecer opciones). Suele ser un callback.

$params = ['notification' => 'este_es_el_callback'];
stream_context_set_params($context, $params);
var_dump(stream_context_get_params($context));
/*
 Devuelve:
array (size=2)
  'notification' => string 'este_es_el_callback' (length=19)
  'options' =>
    array (size=1)
      'http' =>
        array (size=2)
          'method' => string 'GET' (length=3)
          'header' => string 'Content-Type: application/x-www-form-urlencode
Cookie: foo=bar
' (length=65)
 */
  • stream_context_get_options
array stream_context_get_options (resource $stream_or_context)

Devuelve un array con las opciones en el context especificado.

Puedes ver más acerca de las opciones y parámetros de contexts que se pueden utilizar con los sistemas de archivos aquí.

3. Stream metadata

Tras haber podido configurar los headers enviados en una petición HTTP con los stream contexts, ahora vamos a ver como poder extraer esos datos. Hemos podido ver el sitio web example.com pero no sus headers.

$opciones = array(
    'http' => array(
        'method' => "GET",
        'header' =>
            "Content-Type: application/x-www-form-urlencode\r\n" .
            "Cookie: foo=bar\r\n"
    ));
$context = stream_context_create($opciones);
// Ahora podemos usar el context:
echo file_get_contents("http://www.example.com", 0, $context);

Esos headers son parte de los metadatos (metadata), y existe una función para poder extraerlos: stream_get_meta_data(). file_get_contents() devuelve un string con la respuesta, pero al no poder extraer metadatos de ese string, debemos emplear otra función.

fopen() devuelve un stream resource. Vamos a convertir el ejemplo anterior para utilizar esta función:

$opciones = array('http' => array(
'method' => "GET",
'header' => "Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
));
$context = stream_context_create($opciones);
$fp = fopen("http://www.example.com/", "rb", false, $context);
// Podemos ver el contenido con stream_get_contents
echo stream_get_contents($fp);

Para obtener los metadatos de este request, se emplea stream_get_meta_data() sobre el resource:

var_dump(stream_get_meta_data($fp));
/*
array (size=10)
  'wrapper_data' =>
    array (size=9)
      0 => string 'HTTP/1.0 200 OK' (length=15)
      1 => string 'Date: Wed, 25 Nov 2015 19:13:50 GMT' (length=35)
      2 => string 'Server: Apache/2.4.12 (Ubuntu)' (length=30)
      3 => string 'Cache-Control: private' (length=22)
      4 => string 'pragma: no-cache' (length=16)
      5 => string 'expires: -1' (length=11)
      6 => string 'Vary: Accept-Encoding' (length=21)
      7 => string 'Connection: close' (length=17)
      8 => string 'Content-Type: text/html; charset=UTF-8' (length=38)
  'wrapper_type' => string 'http' (length=4)
  'stream_type' => string 'tcp_socket/ssl' (length=14)
  'mode' => string 'rb' (length=2)
  'unread_bytes' => int 1215
  'seekable' => boolean false
  'uri' => string 'http://www.example.com' (length=22)
  'timed_out' => boolean false
  'blocked' => boolean true
  'eof' => boolean false
*/

4. Stream filters

Los filtros permiten transformar los datos cuando se leen o escriben. Las funciones stream_filter_append() y stream_filter_prepend() unen un filtro a un stream (importa el orden en el que se registran):

  • stream_filter_append
resource **stream_filter_append (resource $stream, string $filtername [, int $read_write [, mixed $params ]] )

Por defecto, la función unirá el filtro en modo de lectura si el archivo se abrió para lectura (r, r+), o se unirá al filtro de escritura si el archivo fue abierto para escritura (w, a, w+, a+). El parámetro $read_write puede sobreescribir este comportamiento con las constantes STREAM_FILTER_READ, STREAM_FILTER_WRITE y STREAM_FILTER_ALL.

Vamos a ver un ejemplo con ROT13 como $filtername:

$opciones = array(
'http' => array(
'method' => "GET",
'header' => "Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);

$context = stream_context_create($opciones);

$fp = fopen("http://www.example.com/", "rb", false, $context);
stream_filter_append($fp, "string.rot13", STREAM_FILTER_READ);
echo stream_get_contents($fp);

Existen filtros ya preparados para hacer transformaciones simples, encoding y decoding, compresión e incluso encriptado. Puedes ver una lista con los filtros disponibles aquí.

5. Stream transports

Existe una clase especial de streams, los socket transports, que son algo diferentes a los ya mencionados stream wrappers. Puede verse la lista de socket transports disponibles en el servidor con stream_get_transports(). Algunos ejemplos: tcp, udp, unix, ssl.

Todos trabajan con redes, y hay que usar funciones de stream sockets como fsockopen() para usar dichos transports. No es posible usar funciones como file() o file_get_contents().

Aquí se puede ver una lista de transports disponibles en PHP.

Anterior Siguiente

Indice de contenidos

Básicos Sintaxis básica
Operadores
Operadores bit a bit
Variables
Estructuras de control
Constantes y constructores base
Espacio de nombres
Extensiones
Configuraciones
Variables al descubierto
Recolector de basuras
Rendimiento (Performance)
Funciones Funciones
Argumentos en funciones
Funciones variables
Valores por referencia en funciones
Funciones que devuelven algo
Ámbito de variables
Funciones anónimas y closure's
Cadenas y patrones Las comillas y las cadenas de caracteres
Heredoc y Nowdoc
Comparando cadenas de caracteres
Extracción en cadenas de caracteres
Análisis en cadenas de caracteres
Reemplazos en cadenas de caracteres
Formato de cadena de caracteres
Expresiones regulares (RegEx)
Codificación de caracteres
Codificación en cadenas de caracteres
Arreglos (Array's) Arreglos
Arreglos asociativos
Iterar arreglos
Funciones de arreglos
SPL Arreglos mediante objetos
Conversión de arreglos
Archivos (I/O) Manejo de archivos
Lectura de archivos
Escritura de archivos
Funciones del sistema de archivos
Socket's y archivos
Streams (?)
Seguridad Concepto y funcionamiento CGI
Configurando la seguridad
Seguridad en Sesiones
Ataques XSS
Ataques CSRF
Ataques SQLInjection
Ataques CodeInjection
Ataques EmailInjection
Filtrado de datos de entrada
Escape de datos de salida
Encriptación y contraseñas
Seguridad en el almacenamiento de datos
Seguridad en la subida de datos
SSL y OpenSSL
Base de datos Principios básicos SQL
Los joins en SQL
Principales funciones SQL
Preparando sentencias SQL
Transacciones en SQL
Algo de PDO
Programación Orientada a Objetos Instancias de clases
Modificadores y herencia de clases
Interfaces
Excepciones
Auto-carga (Autoload)
Reflexión (Reflection)
Determinación de tipos (Type hinting)
Constantes de clase
Enlace estático de ejecución (Late Static Binding)
Métodos mágicos
Librería estándar PHP (SPL)
Generadores (Generators)
Traits
Clases abstractas
Formatos de información Algo de XML
Algo de SimpleXML
Algo de XML Parser
Algo de PHP DOM
Algo de Web Services
Web Services con SOAP
Algo de REST
Algo de JSON
Formato de fecha y hora
Características web's Sesiones
Formularios
Métodos GET y POST
Cookies
Protocolo HTTP y sus headers
Autenticación HTTP
Códigos de estado HTTP
Referencias Referencias
Recopilación
Conclusión
Clone this wiki locally