[ Team LiB ] Previous Section Next Section

An Introduction to Streams

A stream is a flow of data that can be read from and written to. Streams were introduced with PHP 4.3. You can work with streams using resource variables and define them using specially structured strings. You might be surprised to discover that we have already done quite a lot of work with streams. Let's revisit the fopen() function:


$fp = fopen( "/path/to/file.txt", "r" );
$wp = fopen( "http://www.example.com", "r" );

We use fopen() to acquire a resource that can then be used with methods such as fgets(). After we have this resource, we can ignore the fact that the source of the stream we are working with is a Web page or a file. It is just a stream.

In the second call to fopen(), the engine provides an HTTP stream rather than a file stream because of the syntax of the path argument. We refer to streams in two parts: the scheme (http in the fragment) and the target (www.example.com). The scheme and the target are separated by the characters '://':


scheme://target
http://www.example.com

In the first call to fopen(), the scheme was omitted and the engine resorted to the default behavior, providing a file stream. Table 14.4 lists some of the schemes PHP supports.

Table 14.4. Some Stream Protocols

scheme://target

Description

file://path/file

The file at path/file on the file system

ftp://host/path

The object at host/path via FTP

ftp://user:pass@host

The object at host/path via FTP (using user/pass)

ftps://host/path

The object at host/path via secure FTP

ftps://user:pass@host

The object at host/path via secure FTP (using user/pass)

http://host/path

The object at host/path via HTTP

http://user:pass@host

The object at host/path via HTTP (with authentication)

https://host/path

The object at host/path via HTTPS

https://user:pass@host

The object at host/path via HTTPS (with authentication)

php://input

Raw POST data

php://output

Output stream to browser or command line

With fopen(), we have a function that handles different stream protocols differently according to type. This is possible because each protocol is managed behind the scenes by its own wrapper. A particular wrapper is invoked by a stream function such as fopen() according to the scheme provided. The target information after the '://' is passed to the wrapper and used to acquire the relevant resource. Also passed to the wrapper are any mode arguments (such as r for read and w for write), options, and an optional context array. Streams sit behind most functions that open flows of data, including file(), file_get_contents(), fsockopen(), and so on. We will deal with fopen() in our examples.

Streams and Contexts

PHP provides a mechanism by which stream wrappers can be passed fine-grained parameters to help them with their reading, writing, or appending. Context options take the form of an array whose key should be the name of the wrapper. The array's value should be an associative array of option names and values. Let's define an option array for an HTTP stream:


$options = array(
      "http"=>array(
        "user_agent"=>"php24-test-script",
        "header"=>"Referer: http://www.example.com/index.html\r\n"
      )
     );

The $options array should be fairly clear. We will be telling our HTTP wrapper to use the Referer header and the user_agent string supplied. Before we can pass these options to fopen(), we must first create a context resource:


$context = stream_context_create( $options );

Table 14.5 lists all the context options the HTTP wrapper accepts.

Table 14.5. The Context Options Supported by the HTTP Wrapper

Key

Description

content

Request information passed after the request header, typically in POST requests

header

One or more request headers; each header should end with a newline

method

The request method, usually GET or POST

user_agent

The User-agent request header (if not overridden by a header option)

In Listing 14.9 we create a simple page that reports on the $_SERVER['HTTP_REFERER'] and $_SERVER['HTTP_USER_AGENT'] elements. We will use this to test our context resource.

Listing 14.9 Reporting the User Agent and Referrer
 1: <!DOCTYPE html PUBLIC
 2:   "-//W3C//DTD XHTML 1.0 Strict//EN"
 3:   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 4: <html>
 5: <head>
 6: <title>Listing 14.9 Reporting User Agent and Referrer</title>
 7: </head>
 8: <body>
 9: <div>
10: <p>
11: Browser: <b><?php print $_SERVER['HTTP_USER_AGENT'] ?></b><br />
12: Referring page: <b><?php print $_SERVER['HTTP_REFERER'] ?></b>
13: </p>
14: </div>
15: </body>
16: </html>

Now we can access this page using an HTTP wrapper. If all goes well, we should see our context options in the output. In Listing 14.10 we create a context resource, passing it to fopen() to display the output from Listing 14.9.

Listing 14.10 Calling fopen() with a Context Resource
 1: <?php
 2: $url="http://p24.corrosive.co.uk:9090/source/listing14.9.php";
 3: $options = array(
 4:         "http"=>array(
 5:           "user_agent"=>"php24-test-script",
 6:          "header"=>"referer: http://www.example.com/index.html\r\n"
 7:         )
 8:       );
 9:
10: $context = stream_context_create( $options );
11:
12: $res = fopen( $url, 'r', 0, $context ) or
13:     die( "could not open page" );
14:
15: while ( ! feof( $res ) ) {
16:   print fgets( $res, 1024 );
17: }
18:
19: ?>

We assign a full URL to the $url variable on line 2. This points to the simple script we created in Listing 14.9. We then create an $options array, passing it to stream_context_create() on line 10 to acquire a context resource. We call fopen() on line 12, passing it our $url variable, a mode string, a zero integer (meaning that we want to pass no special options), and our context resource. Because the $url string begins with http://, an HTTP wrapper is invoked. It makes an HTTP request, using the context options we passed to fopen(). On lines 15 and 16, we use fgets() and feof() to output the stream to the browser. You can see the output from Listing 14.10 in Figure 14.4, confirming that Listing 14.9 reports the headers we set.

Figure 14.4. Calling an HTTP wrapper with a context resource.

graphics/14fig04.gif

graphics/bytheway_icon.gif

You can get a full list of stream wrappers and details of the context options available for each one at http://uk.php.net/manual/en/wrappers.php.


    [ Team LiB ] Previous Section Next Section