164
Chapter 10 Stream and Network Programming
n
whether the stream connection has timed out or not
n
whether the stream has blocked or not
n
whether all data has been read from the stream or not
To get stream metadata, use the
stream_get_meta_data()
function.
<?php
// Chapter 10: Stream and Network Programming
//
// Example 02: stream metdata example
// we will create a stream by opening this stream, and then we’ll
// dump the metadata out to see what’s there
echo “Metadata for file: “ . __FILE__ . “\n\n”;
$fp = fopen(__FILE__, “r”);
var_dump(stream_get_meta_data($fp));
fclose($fp);
?>
Here is the output from running the code example:
array(6) {
[“wrapper_type”]=>
string(9) “plainfile”
[“stream_type”]=>
string(5) “STDIO”
[“unread_bytes”]=>
int(0)
[“timed_out”]=>
or a write pipeline.
What Is the Stream Transport?
At the far end of the pipeline, the furthest away from your PHP script, is the stream
transport.The stream transport is a piece of code that enables the file wrapper to talk
directly with whatever the stream is connected to.
PHP comes with a number of built-in transports:
n
STDIO
The
STDIO
transport is used to talk to normal files, special resources such as
stdin
and
stdout
, and any other types of file supported by your underlying operating
system.
n
socket
The
socket
transport is used to talk to (possibly remote) servers over the network.
PHP automatically chooses the correct transport to use with your choice of file wrapper.
What Is the Stream Context?
The stream context is a piece of data about the stream and about the data passing along
the stream. It is used to pass additional options to the file wrapper or stream transport.
You create the context using the
stream_context_create()
function, and then pass
it as a parameter to
fopen()
the differences to a minimum.
When Should I Use a Socket Instead of a File Wrapper?
Some file wrappers allow you to access (possibly remote) network servers. For example,
the
http
file wrapper allows you to retrieve pages from a web server. Unlike sockets, file
wrappers will hide the details of supporting the application-layer network protocol.
So why would you want to use a socket instead?
You must use a socket if you want to connect to a (possibly remote) network server
that there is no file wrapper for. An example would be connecting to the memcached
caching server.There is no file wrapper that supports the memcached network protocol.
You must use a socket if you want to do something that the file wrapper cannot do—
but is possible through the underlying network protocol. An example would be sending
an XML-RPC message to a (possibly remote) web server. XML-RPC involves sending
XML messages to and from the web server, using the HTTP network protocol.The
http
file wrapper only supports reading from a web server; it does allow you to write
data to the web server. But the underlying HTTP network protocol does support writ-
ing data to a web server, and you can access this network protocol by using a socket
rather than by using a file wrapper.
11 7090 ch10 7/16/04 8:46 AM Page 166
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
167
Connecting to Remote Hosts Using Sockets
What Network Transports Does PHP Support?
You can find this information in the “List of Supported Socket Transports” appendix in
the PHP Manual.
n
tcp
This transport allows you to connect to (possibly remote) network servers using
name or IP address of the server you want to connect to.
<?php
// Chapter 10: Stream and Network Programming
//
// Example 06: Using fsockopen()
// we will open a connection to the PHP Project’s website, and download
// their front page
//
11 7090 ch10 7/16/04 8:46 AM Page 167
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
168
Chapter 10 Stream and Network Programming
// note that what comes back is a redirect, and not the front-page itself
// this is an example of one of the many things that the http file wrapper
// automatically (and transparently) handles for us
$fp = fsockopen (“tcp://www.php.net”, 80, $sock_errno, $sock_errmsg);
fwrite ($fp, “GET /\n”);
while (!feof($fp))
{
echo fgets($fp) . “\n”;
}
fclose($fp);
?>
Sockets created using
fsockopen()
are automatically closed by PHP when your script
ends. Sockets created using
pfsockopen()
are persistent.
Persistent Sockets
fsockopen()
, and the
default_socket_timeout
setting,
only affect attempts to open the socket.This timeout is not used at all for read and write
operations.
11 7090 ch10 7/16/04 8:46 AM Page 168
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
169
Connecting to Remote Hosts Using Sockets
How Do I Use a Socket?
The PHP Streams architecture allows you to treat socket connections as you would
another type of stream.To read from a socket, you can use
fread()
and others.To write
to a socket, you can use
fwrite()
and others.
fread()
and
fwrite()
are binary safe—you can use them to read and write any type
of data that you need to.
Blocking Mode
By default, when PHP creates a new socket, it switches on blocking mode for that
stream.
When blocking mode is on, any functions that attempt to read data from the stream
will wait until there is some data available to be read—or until the socket is closed by
the remote server.
<?php
//
// the difference this time is that we will switch off blocking mode first
//
// finally, we will dump the return value from fgets(), so you can see
// what fgets() returns when trying to read from a blocked stream
$fp = fsockopen(“tcp://www.php.net”, 80, $sock_errno, $sock_errmsg);
stream_set_blocking($fp, false);
echo “Attempting to read from the stream ... this will fail and return\n”;
echo “immediately\n\n”;
$result = fgets($fp);
fclose($fp);
echo “fgets() has returned:\n”;
var_dump($result);
?>
Read/Write Timeouts
Instead of switching off blocking mode, you could use
stream_set_timeout()
to set a
timeout on read/write operations instead.
<?php
// Chapter 10: Stream and Network Programming
//
// Example 10: setting a timeout on a stream
// once again, we will make a connection to the PHP Project’s webserver,
// and attempt to read from the socket without having told the webserver
// what page we want it to serve
//
// the difference this time is that we will set a read/write timeout of
// ten seconds on the stream
//
// once the stream has been closed, the file handle cannot be re-used
// without a new call to fopen() or fsockopen()
$fp = fsockopen (“tcp://www.php.net”, 80, $sock_errno, $sock_errmsg);
fclose($fp);
echo “We have opened and closed the stream. When we attempt to read from\n”;
echo “the stream, PHP will output an error on your screen.\n”;
echo fgets($fp);
?>
11 7090 ch10 7/16/04 8:46 AM Page 171
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.