PHP 5.4.36 Released

stream_get_meta_data

(PHP 4 >= 4.3.0, PHP 5)

stream_get_meta_dataRetrieves header/meta data from streams/file pointers

Descrizione

array stream_get_meta_data ( resource $stream )

Returns information about an existing stream.

Elenco dei parametri

stream

The stream can be any stream created by fopen(), fsockopen() and pfsockopen().

Valori restituiti

The result array contains the following items:

  • timed_out (bool) - TRUE if the stream timed out while waiting for data on the last call to fread() or fgets().

  • blocked (bool) - TRUE if the stream is in blocking IO mode. See stream_set_blocking().

  • eof (bool) - TRUE if the stream has reached end-of-file. Note that for socket streams this member can be TRUE even when unread_bytes is non-zero. To determine if there is more data to be read, use feof() instead of reading this item.

  • unread_bytes (int) - the number of bytes currently contained in the PHP's own internal buffer.

    Nota: You shouldn't use this value in a script.

  • stream_type (string) - a label describing the underlying implementation of the stream.

  • wrapper_type (string) - a label describing the protocol wrapper implementation layered over the stream. See Supported Protocols and Wrappers for more information about wrappers.

  • wrapper_data (mixed) - wrapper specific data attached to this stream. See Supported Protocols and Wrappers for more information about wrappers and their wrapper data.

  • mode (string) - the type of access required for this stream (see Table 1 of the fopen() reference)

  • seekable (bool) - whether the current stream can be seeked.

  • uri (string) - the URI/filename associated with this stream.

Esempi

Example #1 stream_get_meta_data() example

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

if (!
$fp fopen($url'r')) {
    
trigger_error("Unable to open URL ($url)"E_USER_ERROR);
}

$meta stream_get_meta_data($fp);

print_r($meta);

fclose($fp);
?>

Il precedente esempio visualizzerĂ  qualcosa simile 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] => 
)

Note

Nota:

This function does NOT work on sockets created by the Socket extension.

Vedere anche:

add a note add a note

User Contributed Notes 4 notes

up
1
ed at readinged dot com
11 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
php dot chaska at xoxy dot net
6 months 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
0
derkontrollfreak+9hy5l at gmail dot com
3 months ago
Apparently, custom wrappers are always seekable.
up
-1
niels at nise81 dot com
6 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);
To Top