On _php techniques of Stream (stream) in PHP

Source: Internet
Author: User
Tags md5 spl php and wrapper

The concept of flow (stream) originates from the concept of pipeline (pipe) in Unix. In Unix, pipelines are 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 input and output streams, while the other can be set on the periphery of the flow, such as buffer flow, so you can get more flow processing methods.

The stream in PHP and the stream in Java are actually the same concept, just a little bit simpler. Because PHP is primarily used for web development, the concept of "streaming" 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, exceptions, filters, etc. are referenced in the implementation of Java, in the concept and principle of expatiating.

For example, the following is a section of the PHP SPL standard library usage (traversal directory, find fixed conditions of the file):

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

Java also has and its expatiating code:

public class directorycontents
{public
 static void Main (string[] args) throws IOException
 {
   File f = new File ("."); Current directory
   FilenameFilter textfilter = new FilenameFilter ()
   {public
     Boolean accept (File 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 ("directory:");
     }
     else
     {
       System.out.print ("   file:");
     }
     System.out.println (File.getcanonicalpath ());}}

To take this example, on the one hand, PHP and Java in many aspects of the concept is the same, mastering a language to understand another language will be very helpful; On the other hand, this example also helps us to mention the following filter flow-filter. In fact, is also a design pattern embodiment.

We can take a few examples to understand the use of stream series functions first.

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

$post _ =array (
 ' author ' => ' Gonn ',
 ' mail ' => ' gonn@nowamagic.net ', '
 url ' => ' http://') www.nowamagic.net/',
 ' text ' => ' welcome access 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 Stream_socket implementation, which is very simple, just open the socket code to the following can be:

Copy Code code as follows:

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

Let's look at one more example of a stream:

File_get_contents functions are commonly used to read the contents of a file, but this function can also be used to crawl remote URLs and play a similar role in 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 that the third parameter, $context, the HTTP streaming context, can be understood as a pipe that is nested on the file_get_contents function. Similarly, we can also create an FTP stream, a socket stream, and put 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 stream that acts on the input/output stream of some protocol. This usage and concept, in fact, and Java in the flow is not a big difference, such as Java often have such a writing:

Copy Code code as follows:

New DataOutputStream (New Bufferedoutputstream (FileName));

A laminar flow is nested in another laminar flow, and PHP has the same as the wonderful.

Let's take a look at the role of the filter flow:

$fp = fopen (' c:/test.txt ', ' w+ ');
* * ROT13 filter function on the write stream
/stream_filter_append ($fp, "string.rot13", stream_filter_write);
/* Write data after ROT13 filter processing * *
fwrite ($fp, "This is a test\n");
Rewind ($FP);
/* Read the written data, unique nature is processed by the characters of the * *
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, the same effect on the read and write stream, then the data read and write will be processed by the ROT13 filter, the data we read is the same as the original data written.

You might be surprised at the Stream_filter_append "string.rot13" variable, which is actually a built-in filter in PHP.

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

$streamlist = Stream_get_filters ();
Print_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
 [a] => zlib.*
 [one] => bzip2.*
)

Naturally, we 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 read by other pipelines return
   psfs_pass_on
 }
}
Stream_filter_register ("String.md5", "Md5_filter");

Note: The filter name can be arbitrarily taken.

Then we can use the "string.md5" for our custom filter.

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

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

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 handle the input stream, but also callback a function for logging.

You can use this:

Copy Code code as follows:

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

PHP Stream Stream Series function also has a very important flow, is the wrapper class stream streamwrapper. Using wrapper flows enables different types of protocols to manipulate data using the same interface. I'll talk about it later.

The above mentioned is the entire content of this article, I hope you can enjoy.

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.