Home >Backend Development >PHP Tutorial >PHP Master | Understanding Streams in PHP

PHP Master | Understanding Streams in PHP

Lisa Kudrow
Lisa KudrowOriginal
2025-02-23 10:38:14700browse

PHP Master | Understanding Streams in PHP

Core points

  • PHP streaming is a powerful tool for generalizing file, network and data compression operations. They can be read or written linearly and can be fseek() anywhere in the stream. Each stream has a wrapper for handling specific protocols or encodings.
  • PHP provides built-in wrappers, protocols, and filters, and allows the creation and registration of custom wrappers, protocols, and filters. The default wrapper is 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.
  • Stream context is a stream-specific parameter or option that can modify and enhance the behavior of the wrapper. They can be used to avoid the use of cURLs in simple network operations and can be modified or created individually for different purposes. Streams can be used to create virtual file system wrappers for PaaS providers and can be used to build custom wrappers and filters for applications that implement custom file formats and encodings.

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:

<code class="language-php"><?php
print_r(stream_get_transports());
print_r(stream_get_wrappers());
print_r(stream_get_filters());
?></code>

My installation output is as follows:

<code class="language-php"><?php
print_r(stream_get_transports());
print_r(stream_get_wrappers());
print_r(stream_get_filters());
?></code>

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:

<code class="language-bash">curl -d "Hello World" -d "foo=bar&name=John" http://localhost/dev/streams/php_input.php</code>

Please note that the first packet cannot be accessed from the $_POST array. However, if we use readfile('php://input') instead, we will get:

<code class="language-php">Array
(
    [foo] => bar
    [name] => John
)</code>

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.

<code class="language-php"><?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");
?></code>

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:

<code class="language-php"><?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');
?></code>

We modified the default context option, but we can also create alternative contexts for use alone.

<code class="language-php">Array
(
    [Host] => localhost
    [Auth] => SecretAuthToken
    [Content-type] => application/x-www-form-urlencoded
    [Content-length] => 11
)</code>

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn