Core points
fseek()
anywhere in the stream. Each stream has a wrapper for handling specific protocols or encodings. file://
, which is used every time you access the file system. Other wrappers include wrappers for HTTP, Amazon S3, MS Excel, Google Storage, Dropbox, and Twitter. PHP streams are resources provided by PHP and we often use them transparently, but they can also be very powerful tools. By learning how to harness their power, we can take our applications to a higher level. The PHP manual has a good description of streaming: > Streaming was introduced in PHP 4.3.0 as a way to generalize files, networks, data compression, and other operations that share a common set of functions and uses. Simply put, a stream is a resource object that exhibits streamable behavior. That is, it can be read or written linearly and may be able to fseek()
anywhere in the stream.
Each stream has an implementation wrapper that contains additional code needed to handle a specific protocol or encoding. PHP provides some built-in wrappers that we can easily create and register custom wrappers. We can even use context and filters to modify or enhance the behavior of the wrapper.
Flow basics
The reference format of the stream is <scheme>://<target></target></scheme>
. <scheme></scheme>
is the name of the wrapper, and <target></target>
will vary according to the syntax of the wrapper. The default wrapper is file://
, which means we use streams every time we access the file system. For example, we can write readfile('/path/to/somefile.txt')
or readfile('file:///path/to/somefile.txt')
and get the same result. If we use readfile('http://google.com/')
instead, then we tell PHP to use the HTTP stream wrapper. As mentioned earlier, PHP provides some built-in wrappers, protocols, and filters. To understand what wrappers are installed on our machine, we can use:
<?php print_r(stream_get_transports()); print_r(stream_get_wrappers()); print_r(stream_get_filters()); ?>
My installation output is as follows:
<?php print_r(stream_get_transports()); print_r(stream_get_wrappers()); print_r(stream_get_filters()); ?>
A good set of tools, isn't it? Additionally, we can write or use third-party streams for Amazon S3, MS Excel, Google Storage, Dropbox and even Twitter.
php:// wrapper
PHP has its own wrapper to access the language's I/O stream. There are basic php://stdin
, php://stdout
and php://stderr
wrappers map the default I/O resources, and we also php://input
, a read-only stream with the original body of the POST request. This is very convenient when we deal with remote services that put the data payload inside the POST request body. Let's use cURL for quick test:
<code>Array ( [0] => tcp [1] => udp [2] => unix [3] => udg [4] => ssl [5] => sslv3 [6] => sslv2 [7] => tls ) Array ( [0] => https [1] => ftps [2] => compress.zlib [3] => compress.bzip2 [4] => php [5] => file [6] => glob [7] => data [8] => http [9] => ftp [10] => zip [11] => phar ) 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.* )</code>
The result of print_r($_POST)
in response to the PHP script will be:
curl -d "Hello World" -d "foo=bar&name=John" http://localhost/dev/streams/php_input.php
Please note that the first packet cannot be accessed from the $_POST
array. However, if we use readfile('php://input')
instead, we will get:
Array ( [foo] => bar [name] => John )
PHP 5.1 introduces php://memory
and php://temp
stream wrappers for reading and writing temporary data. As the name implies, data is stored in memory or in temporary files managed by the underlying system, respectively. There is also php://filter
, a meta wrapper designed to apply filters when opening streams using functions such as readfile()
or file_get_contents()
/stream_get_contents()
.
<code>Hello World&foo=bar&name=John</code>
The first example uses a filter to encode the data written to the disk, while the second example applies two cascading filters to read data from a remote URL. The result can range from very basic to very powerful in our application.
Flow context
Context is a set of stream-specific parameters or options that can modify and enhance the behavior of our wrappers. A common use context is to modify HTTP wrappers. This allows us to avoid using cURL in simple network operations.
<?php // 写入编码数据 file_put_contents("php://filter/write=string.rot13/resource=file:///path/to/somefile.txt","Hello World"); // 读取数据并进行编码/解码 readfile("php://filter/read=string.toupper|string.rot13/resource=http://www.google.com"); ?>
First, we define an array of options, which is an array of arrays in the format $array['wrapper']['option_name']
(the available context options vary depending on the specific wrapper). Then we call stream_context_get_default()
, which returns the default context and accepts an optional array of options to apply. The readfile()
statement uses these settings to get content. In this example, the content is sent in the body of the request, so the remote script will use php://input
to read it. We can access the header using apache_request_headers()
and get:
<?php $opts = array( 'http' => array( 'method' => "POST", 'header' => "Auth: SecretAuthToken\r\n" . "Content-type: application/x-www-form-urlencoded\r\n" . "Content-length: " . strlen("Hello World"), 'content' => 'Hello World' ) ); $default = stream_context_get_default($opts); readfile('http://localhost/dev/streams/php_input.php'); ?>
We modified the default context option, but we can also create alternative contexts for use alone.
Array ( [Host] => localhost [Auth] => SecretAuthToken [Content-type] => application/x-www-form-urlencoded [Content-length] => 11 )
Conclusion
How do we use the power of flow in the real world? Where else can we go? As we can see, streams share some or all the file system-related functions, so the first use that comes to my mind is a series of virtual file system wrappers for PaaS provisioning with Heroku or AppFog, such as Heroku or AppFog. Use together. With little effort, we can port our applications from standard hosting services to these cloud services and enjoy the benefits. Additionally – I will show in a subsequent post – we can build custom wrappers and filters for our applications that implement custom file formats and encodings.
(The FAQs part is omitted here due to space limitations.)
The above is the detailed content of PHP Master | Understanding Streams in PHP. For more information, please follow other related articles on the PHP Chinese website!