Learn about the concept and usage of stream (stream) in PHP

Source: Internet
Author: User
Tags spl

Stream is one of the most overlooked function series in PHP development (SPL series, stream series, pack function, encapsulation protocol), but it is a useful and important function. Stream can be translated as "stream", in Java, flow is a very important concept.

The concept of stream is derived from the concept of piping (pipe) in Unix. In Unix, a pipeline is an uninterrupted stream of bytes used to communicate between programs or processes, or to read and write peripherals, external files, and so on. According to the direction of the flow can be divided into the input and output streams, but also on the periphery of other flows, such as buffer flow, so that more flow processing methods can be obtained.

The stream in PHP and the stream in Java are actually the same concept, just a little bit simpler. Since PHP is primarily used for web development, the concept of "flow" is less mentioned. If you have a Java base, it's easier to understand the flow in PHP. In fact, many of the advanced features in PHP, such as SPL, anomalies, filters, and so on are referenced in the implementation of Java, in the concept and principle of expatiating.

For example, here is the use of a PHP SPL standard library (traversing directories to find fixed-condition files):

Class Recursivefilefilteriterator extends filteriterator{    //Meet the condition extension    protected $ext = array (' jpg ', ' gif ');    /**     * Provides $path and generates a corresponding directory iterator */     public    function __construct ($path)    {        parent::__construct (new Recursiveiteratoriterator (New Recursivedirectoryiterator ($path)));    }    /**     * Check if the file extension meets the criteria     *    /Public Function accept ()    {        $item = $this->getinneriterator ();        if ($item->isfile () && In_array (PathInfo ($item->getfilename (), pathinfo_extension), $this->ext))        {            return TRUE;}}    } Instantiate the foreach (New Recursivefilefilteriterator (' D:/history ') as $item) {    echo $item. Php_eol;}

Java also has code for its expatiating:

public class directorycontents{public static void Main (string[] args) throws IOException { File F = new file ("."); Current directory FilenameFilter TextFilter = new FilenameFilter () {public Boolean accept (Fil                e dir, string name) {String lowercasename = Name.tolowercase ();                if (Lowercasename.endswith (". txt")) {return true;                } else {return false;        }            }        };        file[] files = f.listfiles (TextFilter); for (File file:files) {if (File.isdirectory ()) {System.out.print ("director            Y: ");            } else {System.out.print ("file:");        } System.out.println (File.getcanonicalpath ()); }    }}

This example shows that PHP and Java have the same concept in many aspects, that mastering one language can be very helpful in understanding another language, and this example also helps us to refer to the filter flow-filter below. In fact, it is also a design pattern embodiment.

We can start with a few examples to understand the use of stream series functions.

Here is an example of using a socket to fetch data:

$post _ =array (' Author ' = ' gonn ', ' mail ' = ' [email protected] ', ' url ' = ' http://www.nowamagic.net/', ' text ' = > ' Welcome to Concise modern Magic '); $data =http_build_query ($post _); $fp = Fsockopen ("Nowamagic.net", $errno, $errstr, 5); $out = "Post Http://nowamagic.net/news/1/comment http/1.1\r\n "; $out. =" host:typecho.org\r\n "; $out. =" user-agent:mozilla/5.0 ( Windows; U Windows NT 6.1; ZH-CN; rv:1.9.2.13) gecko/20101203 firefox/3.6.13 "." \ r \ n "; $out. =" content-type:application/x-www-form-urlencoded\r\n "; $out. =" phpsessid= 082b0cc33cc7e6df1f87502c456c3eb0\r\n "; $out. =" Content-length: ". Strlen ($data). "\ r \ n"; $out. = "connection:close\r\n\r\n"; $out. = $data. " \r\n\r\n "; fwrite ($fp, $out), while (!feof ($fp)) {    echo fgets ($FP, 1280);} Fclose ($FP);

We can also use the Stream_socket implementation, which is very simple, just need to open the socket code to replace the following:

$fp = Stream_socket_client ("tcp://nowamagic.net:80", $errno, $errstr, 3);

Let's look at a stream example:

The File_get_contents function is commonly used to read the contents of a file, but this function can also be used to crawl remote URLs, playing a similar role as curl.

$opts = Array (' http ' =>array (   ' method ' = ' = ' POST ', ' header ' = ') '   content-type:application/ x-www-form-urlencoded\r\n ".  " Content-length: ". Strlen ($data). "\ r \ n",   ' content ' = $data)); $context = Stream_context_create ($opts); file_get_contents (' http:// Nowamagic.net/news/1/comment ', false, $context);

Note the third argument, $context, the HTTP stream context, can be understood as a pipe set on the File_get_contents function. Similarly, we can also create an FTP stream, a socket stream, and set it in the corresponding function.

More about Stream_context_create, you can refer to: PHP function Completion: stream_context_create () simulation post/get.

The function of the two stream series mentioned above is a wrapper-like flow that acts on the input and output stream of some kind of protocol. Such use and concept, in fact, and Java in the flow is not a big difference, such as Java often have such a way of writing:

New DataOutputStream (New Bufferedoutputstream (New FileOutputStream (FileName)));

A laminar layer is nested in another laminar flow, and PHP is similar to the wonderful.

Let's look at the effect of a filter flow:

$fp = fopen (' c:/test.txt ', ' w+ ');/* The ROT13 filter acts on the write stream */stream_filter_append ($fp, "string.rot13", Stream_filter_write) */* The data written is processed by the ROT13 filter */fwrite ($FP, "This is a test\n"), Rewind ($FP);/* reads the written data, the original nature is the processed character */fpassthru ($FP); fclose ($fp);//OUTPUT:GUVF VF n GRFG

In the above example, if we set the type of the filter to Stream_filter_all, that is, at the same time on the read-write stream, the read-write data will be processed by the ROT13 filter, and the data we read is consistent with the original data being written.

You may be surprised by the stream_filter_append of the "string.rot13" variable, which is actually a filter built into PHP.

Use the following method to print out the PHP built-in flow:

$streamlist = Stream_get_filters ();p rint_r ($streamlist);

Output:

Array (    [0] = convert.iconv.*    [1] = mcrypt.*    [2] = mdecrypt.*    [3] = = string.rot13    [4 ] = String.ToUpper    [5] = = String.ToLower    [6] = = String.strip_tags    [7] = = Convert.*    [8] = > Consumed    [9] = Dechunk    [ten] = zlib.*    [one] = bzip2.*)

Naturally, we will think of defining our own filters, which is not difficult:

Class Md5_filter extends php_user_filter{    function filter ($in, $out, & $consumed, $closing)    {        while ($bucket = stream_bucket_make_writeable ($in))        {            $bucket->data = MD5 ($bucket->data);            $consumed + = $bucket->datalen;            Stream_bucket_append ($out, $bucket);        }        Data processing is successful and can be used for other pipelines to read        return psfs_pass_on;}    } Stream_filter_register ("String.md5", "Md5_filter");

Note: The filter name can be arbitrarily taken.

You can then use the "String.md5" as our custom filter.

The way the filter is written seems to be a bit confusing, in fact we just need to look at the structure of the Php_user_filter class and the built-in approach to understanding it.

Filter flow is the most suitable to do is the file format conversion, including compression, codec, in addition to these "partial gate" usage, the filter stream is more useful in debugging and logging functions, such as in the socket development, register a filter stream to log records. For example, the following:

Class Md5_filter extends php_user_filter{public    function Filter ($in, $out, & $consumed, $closing)    {        $ Data= "";        while ($bucket = stream_bucket_make_writeable ($in))        {            $bucket->data = MD5 ($bucket->data);            $consumed + = $bucket->datalen;            Stream_bucket_append ($out, $bucket);        }        Call_user_func ($this->params, $data);        return psfs_pass_on;}    } $callback = function ($data) {    file_put_contents ("C:\log.txt", Date ("Y-m-d h:i"). " \ r \ n ");};

This filter can not only process the input stream, but also callback a function for logging.

You can use this:

Stream_filter_prepend ($fp, "String.md5", Stream_filter_write, $callback);

There is also a very important stream in the Stream series function in PHP, which is the wrapper class flow streamwrapper. Using wrapper flow allows different types of protocols to manipulate data using the same interface. I'll talk about this later.

Learn about the concept and usage of stream (stream) in PHP

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.