This post covers the Streams section of the Input/Output chapter when studying for the Zend PHP 7 Certification.
Streams are a way of generalising file, network, data compression, and other operations which share a common set of functions and uses.
A stream is usually referenced as scheme://target
where scheme
is the wrapper or protocol being used. target
is usually a file name or a URL, but it depends on the scheme defined.
A list of supported protocols and wrappers can be seen below.
file://
— Accessing local filesystemhttp://
— Accessing HTTP(s) URLsftp://
— Accessing FTP(s) URLsphp://
— Accessing various I/O streamszlib://
— Compression Streamsdata://
— Data (RFC 2397)glob://
— Find pathnames matching patternphar://
— PHP Archivessh2://
— Secure Shell 2rar://
— RARogg://
— Audio streamsexpect://
— Process Interaction StreamsThe most common form of reading a file probably involves using the file_get_contents()
function where the file name is passed in as an argument.
<?php $localfile = file_get_contents("/home/bar/foo.txt");
However streams can also be specified. For example, the below is identical to the above except that it used the file://
protocol.
$localfile = file_get_contents("file:///home/bar/foo.txt");
Other example of protocols in use can be seen below:
/* Read remote file from www.example.com using HTTP */ $httpfile = file_get_contents("http://www.example.com/foo.txt"); /* Read remote file from www.example.com using HTTPS */ $httpsfile = file_get_contents("https://www.example.com/foo.txt"); /* Read remote file from ftp.example.com using FTP */ $ftpfile = file_get_contents("ftp://user:pass@ftp.example.com/foo.txt"); /* Read remote file from ftp.example.com using FTPS */ $ftpsfile = file_get_contents("ftps://user:pass@ftp.example.com/foo.txt");
PHP gives you the ability to create custom stream wrappers by using stream_wrapper_register()
function. This function takes three parameters:
STREAM_IS_URL
if protocol is a URL protocol. Default is 0, local stream.<?php $existed = in_array("var", stream_get_wrappers()); if ($existed) { stream_wrapper_unregister("var"); } stream_wrapper_register("var", "VariableStream"); $myvar = ""; $fp = fopen("var://myvar", "r+");
Stream contexts are a set of parameters and wrapper options that can modify a stream’s behaviour.
In this case, the stream context can be passed as a parameter in fopen()
and file_get_contents()
to tell the functions to send that authorisation header and those options to the wrapper.
You can create a stream context using the stream_context_create()
function.
<?php $opts = array( 'http'=>array( 'method'=>"GET", 'header'=>"Accept-language: en\r\n" . "Cookie: foo=bar\r\n" ) ); $context = stream_context_create($opts); /* Sends an http request to www.example.com with additional headers shown above */ $fp = fopen('http://www.example.com', 'r', false, $context); fpassthru($fp); fclose($fp);
The stream_context_set_params()
function sets parameters for a stream/wrapper/context.
bool stream_context_set_params ( resource $stream_or_context , array $params )
The stream_copy_to_stream()
function copies data from one stream to another. There can be up to 4 parameters passed in this function.
The return value is the number of bytes copied.
<?php $src = fopen('http://www.example.com', 'r'); $dest1 = fopen('destination.txt', 'w'); echo stream_copy_to_stream($src, $dest1, 1024) . " bytes copied to destination.txt";
A filter is a final piece of code which may perform operations on data as it is being read from or written to a stream. Any number of filters may be stacked onto a stream. Current filters can be seen using the stream_get_filters()
function.
$streamlist = stream_get_filters(); print_r($streamlist); // Outputs: Array ( [0] => zlib.* [1] => bzip2.* [2] => convert.iconv.* [3] => string.rot13 [4] => string.toupper [5] => string.tolower [6] => string.strip_tags [7] => convert.* [8] => consumed [9] => dechunk [10] => mcrypt.* [11] => mdecrypt.* )
Custom filters can be registered using the stream_filter_register()
function. The second parameter (class name) must extend the php_user_filter
class.
<?php /* Define our filter class */ class strtoupper_filter extends php_user_filter { function filter($in, $out, &$consumed, $closing) { while ($bucket = stream_bucket_make_writeable($in)) { $bucket->data = strtoupper($bucket->data); $consumed += $bucket->datalen; stream_bucket_append($out, $bucket); } return PSFS_PASS_ON; } } /* Register our filter with PHP */ stream_filter_register("strtoupper", "strtoupper_filter") or die("Failed to register filter");
You can then add the custom filter to the stream using the stream_filter_append()
function.
$fp = fopen("foo-bar.txt", "w"); /* Attach the registered filter to the stream just opened */ stream_filter_append($fp, "strtoupper");
Note: This article is based on PHP version 7.1.