PHPCon Poland 2024

stream_get_meta_data

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

stream_get_meta_dataRecuperar meta-información o de cabecera de punteros a flujos/archivo

Descripción

stream_get_meta_data(resource $stream): array

Devuelve información sobre un stream (flujo) existente.

Parámetros

stream

El flujo puede ser cualquier flujo creado por fopen(), fsockopen() y pfsockopen().

Valores devueltos

La matriz resultante contiene los siguientes elementos:

  • timed_out (bool) - true si el flujo agota el tiempo mientras espera información en la última llamada a fread() o fgets().

  • blocked (bool) - true si el flujo está en el modo de bloqueo IO. Véase stream_set_blocking().

  • eof (bool) - true si el flujo ha alcanzado la marca eof (end-of-file, final de archivo). Observe que para flujos de socket este miembro puede ser true incluso cuando unread_bytes no es cero. Para determinar si hay más información para leer, use feof() en vez de leer este elemento.

  • unread_bytes (int) - el número de bytes contenidos actualmente en el propio buffer interno de PHP.

    Nota: No se debería usar este valor en un script.

  • stream_type (string) - una etiqueta que describe la implementación subyacente del flujo.

  • wrapper_type (string) - una etiqueta que describe la implementación de la envoltura de protocolo que traslapa al flujo. Véase Protocolos y Envolturas soportados para más información acerca de envolturas.

  • wrapper_data (mixed) - la información específica de la envoltura vinculada a este flujo. Véase Protocolos y Envolturas soportados para más información acerca de envolturas y su infomración de envoltura.

  • mode (string) - el tipo de acceso requerido para este flujo (véase la Tabla 1 de la referencia de fopen())

  • seekable (bool) - si el flujo acutal puede ser buscado.

  • uri (string) - la URI/nombre de archivo asociado con este flujo.

Ejemplos

Ejemplo #1 Ejemplo de stream_get_meta_data()

<?php
$url
= 'http://www.example.com/';

if (!
$fp = fopen($url, 'r')) {
trigger_error("Incapaz de abrir la URL ($url)", E_USER_ERROR);
}

$meta = stream_get_meta_data($fp);

print_r($meta);

fclose($fp);
?>

El resultado del ejemplo sería algo similar a:

Array
(
    [wrapper_data] => Array
        (
            [0] => HTTP/1.1 200 OK
            [1] => Server: Apache/2.2.3 (Red Hat)
            [2] => Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT
            [3] => ETag: "b300b4-1b6-4059a80bfd280"
            [4] => Accept-Ranges: bytes
            [5] => Content-Type: text/html; charset=UTF-8
            [6] => Set-Cookie: FOO=BAR; expires=Fri, 21-Dec-2012 12:00:00 GMT; path=/; domain=.example.com
            [6] => Connection: close     
            [7] => Date: Fri, 16 Oct 2009 12:00:00 GMT
            [8] => Age: 1164   
            [9] => Content-Length: 438
        )

    [wrapper_type] => http
    [stream_type] => tcp_socket/ssl
    [mode] => r
    [unread_bytes] => 438
    [seekable] => 
    [uri] => http://www.example.com/
    [timed_out] => 
    [blocked] => 1
    [eof] => 
)

Notas

Nota:

Esta función NO funciona en sockets creados por la extensión Socket.

Ver también

add a note

User Contributed Notes 4 notes

up
10
php dot chaska at xoxy dot net
10 years ago
In PHP 5.4.24 and 5.4.25, this command does not correctly return the stream blocking status. It always returns ['blocked'] == 1 regardless of the actual blocking mode. A call to stream_set_blocking($stream, 0) will succeed (return TRUE) and subsequent calls to stream_get_contents($stream) will NOT block, even though a call to stream_get_meta_data($stream) will return 'blocked' == 1. Hopefully this will save some people a bunch of debugging time.

See bug report #47918 for more information (http://bugs.php.net/bug.php?id=47918).

Proof:
<?php
$d
= array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('file', 'error.log', 'a')
);

$p = proc_open('php -S localhost:8000', $d, $pipes);

if (!
is_resource($p)) die("proc_open() failed\n");

// Set child's stdout pipe to non-blocking.
if (!stream_set_blocking($pipes[1], 0)) {
die(
"stream_set_blocking() failed\n");
}
else {
echo
"Non-blocking mode should be set.\n";
}

// View the status of that same pipe.
// Note that 'blocked' is 1! This appears to be wrong.
print_r(stream_get_meta_data($pipes[1]));

// Try to read something. This will block if in blocking mode.
// If it does not block, stream_set_blocking() worked but
// stream_get_meta_data() is lying about blocking mode.
$data = stream_get_contents($pipes[1]);

echo
"data = '$data'\n";
?>

Output:
Non-blocking mode should be set.
Array
(
[stream_type] => STDIO
[mode] => r
[unread_bytes] => 0
[seekable] =>
[timed_out] =>
[blocked] => 1 // << claims to be in blocking mode
[eof] =>
)
data = '' // this would never appear if we blocked.
up
5
ed at readinged dot com
21 years ago
Below is a function I wrote to pull the "Last-Modified" header from a given URL. In PHP version 4.3 and above, it takes advantage of the stream_get_meta_data function, and in older version it uses a conventional GET procedure. On failure to connect to $url, it returns NULL. If the server does not return the Last-Modified header, it returns the current time. All times are returned in PHP's integer format (seconds since epoch).

Use it as so:

$last_modified = stream_last_modified('http://www.php.net/news.rss');
if (!is_null($last_modified))
if ($last_modified < time()-3600) //Older than an hour
echo 'URL is older than an hour.';
else
echo 'URL is fairly new.';
else
echo 'Invalid URL!';

function stream_last_modified($url)
{
if (function_exists('version_compare') && version_compare(phpversion(), '4.3.0') > 0)
{
if (!($fp = @fopen($url, 'r')))
return NULL;

$meta = stream_get_meta_data($fp);
for ($j = 0; isset($meta['wrapper_data'][$j]); $j++)
{
if (strstr(strtolower($meta['wrapper_data'][$j]), 'last-modified'))
{
$modtime = substr($meta['wrapper_data'][$j], 15);
break;
}
}
fclose($fp);
}
else
{
$parts = parse_url($url);
$host = $parts['host'];
$path = $parts['path'];

if (!($fp = @fsockopen($host, 80)))
return NULL;

$req = "HEAD $path HTTP/1.0\r\nUser-Agent: PHP/".phpversion()."\r\nHost: $host:80\r\nAccept: */*\r\n\r\n";
fputs($fp, $req);

while (!feof($fp))
{
$str = fgets($fp, 4096);
if (strstr(strtolower($str), 'last-modified'))
{
$modtime = substr($str, 15);
break;
}
}
fclose($fp);
}
return isset($modtime) ? strtotime($modtime) : time();
}
up
-1
niels at nise81 dot com
16 years ago
here is just an example how to read out all meta data.
how ever I found out that the "seekable"-entry doesn't exist in most of the streaming media files.

if (!($fp = @fopen($url, 'r')))
return NULL;

$meta = stream_get_meta_data($fp);

foreach(array_keys($meta) as $h){
$v = $meta[$h];
echo "".$h.": ".$v."<br/>";
if(is_array($v)){
foreach(array_keys($v) as $hh){
$vv = $v[$hh];
echo "_".$hh.": ".$vv."<br/>";
}
}
}
fclose($fp);
up
-7
derkontrollfreak+9hy5l at gmail dot com
9 years ago
Apparently, custom wrappers are always seekable.
To Top