Streams ist ein leistungsstarkes Tool, das von PHP bereitgestellt wird. Wir verwenden es oft versehentlich. Wenn wir es gut nutzen, wird es die Produktivität von PHP erheblich verbessern. Wenn Sie die Leistungsfähigkeit von Streams nutzen, heben Sie Ihre Anwendungen auf die nächste Stufe.
Das Folgende ist eine Beschreibung von Streams im PHP-Handbuch:
Streams wurden in der PHP-Version 4.3.0 eingeführt. Es wird verwendet, um Dateien, Netzwerke usw. zu vereinheitlichen Der Betriebsmodus der Datenkomprimierung und anderer Klassendateien bietet eine Reihe gemeinsamer Funktionsschnittstellen für diese Klassendateioperationen. Kurz gesagt ist ein Stream ein Ressourcenobjekt mit Streaming-Verhalten. Mit anderen Worten: Wir können den Stream linear lesen und schreiben. Und Sie können fseek() verwenden, um zu jeder Position im Stream zu springen.
Jedes Streams-Objekt verfügt über eine Wrapper-Klasse, in der relevanter Code für die Handhabung spezieller Protokolle und Codierungen hinzugefügt werden kann. Einige häufig verwendete Verpackungsklassen wurden in PHP integriert, und wir können auch benutzerdefinierte Verpackungsklassen erstellen und registrieren. Wir können die Wrapper-Klasse sogar mithilfe vorhandener Kontexte und Filter ändern und erweitern.
Stream-Grundlagen
Stream kann über
Die Standardverpackungsklasse von PHP ist file://, was bedeutet, dass wir beim Zugriff auf das Dateisystem tatsächlich einen Stream verwenden. Wir können den Inhalt der Datei auf die folgenden zwei Arten lesen: readfile('/path/to/somefile.txt') oder readfile('file:///path/to/somefile.txt'). . Wenn Sie readfile('http://google.com/') verwenden, wählt PHP die HTTP-Stream-Wrapper-Klasse aus, die ausgeführt werden soll.
Wie oben erwähnt, bietet PHP viele integrierte Paketklassen, Protokolle und Filter. Mit der unten beschriebenen Methode können Sie die von dieser Maschine unterstützten Verpackungsklassen abfragen:
<?php print_r(stream_get_transports()); print_r(stream_get_wrappers()); print_r(stream_get_filters());
Das Ausgabeergebnis auf meiner Maschine ist:
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.* )
Es stehen viele Funktionen zur Verfügung. , sieht ziemlich gut aus, oder?
Zusätzlich zu den oben genannten integrierten Streams können wir auch weitere Streams von Drittanbietern für Amazon S3, MS Excel, Google Storage, Dropbox und sogar Twitter schreiben.
php:// Wrapper-Klasse
PHP verfügt über eine integrierte Wrapper-Klasse für die Verarbeitung von I/O-Streams in dieser Sprache. Es kann in mehrere Kategorien unterteilt werden: php://stdin, php://stdout und php://stderr. Gleichzeitig stellt PHP auch die Eingabe php:// bereit, über die schreibgeschützt auf den Rohtext in der POST-Anfrage zugegriffen werden kann. Dies ist eine sehr nützliche Funktion, insbesondere wenn es um Remote-Dienste geht, die Datennutzlasten in POST-Anfragen einbetten.
Als nächstes verwenden wir das cURL-Tool, um einen einfachen Test durchzuführen:
curl -d "Hello World" -d "foo=bar&name=John" <a href="http://localhost/dev/streams/php_input.php">http://localhost/dev/streams/php_input.php</a>
Die Testergebnisse der Verwendung von print_r ($_POST) im PHP-Skript sind wie folgt:
Array ( [foo] => bar [name] => John )
Wir beachten, dass auf das erste Datenelement im $_POST-Array nicht zugegriffen werden kann. Wenn wir jedoch readfile('php://input') verwenden, ist das Ergebnis anders:
Hello World&foo=bar&name=John
PHP 5.1 fügt zwei weitere Pakete hinzu: php://memory und php://tempstream Klasse zum Lesen und Schreiben temporärer Daten. Wie der Name der Wrapper-Klasse schon sagt, werden diese Daten im Speicher oder in temporären Dateien im zugrunde liegenden System gespeichert.
php://filter ist eine Metaverpackungsklasse, die zum Hinzufügen von Filterfunktionen zum Stream verwendet wird. Der Filter wird aktiviert, wenn ein Stream mit readfile() oder file_get_contents()/stream_get_contents() geöffnet wird. Das Folgende ist ein Beispiel:
<?php // Write encoded data file_put_contents("php://filter/write=string.rot13/resource=file:///path/to/somefile.txt","Hello World"); // Read data and encode/decode readfile("php://filter/read=string.toupper|string.rot13/resource=http://www.google.com");
Im ersten Beispiel wird ein Filter verwendet, um die auf der Festplatte gespeicherten Daten zu kodieren. Im zweiten Beispiel werden zwei kaskadierte Filter zum Lesen von Daten von einer Remote-URL verwendet. Die Verwendung von Filtern kann Ihrer Anwendung äußerst leistungsstarke Funktionen verleihen.
Stream-Kontext
Kontext ist eine Reihe streambezogener Parameter oder Optionen. Verwenden Sie den Kontext, um das Verhalten der Wrapper-Klasse zu ändern oder zu verbessern. Beispielsweise ist die Verwendung von Kontext zum Ändern des HTTP-Wrappers ein häufig verwendetes Verwendungsszenario. Auf diese Weise können wir einige einfache Netzwerkvorgänge ausführen, ohne das cURL-Tool zu verwenden. Hier ist ein Beispiel:
<?php $opts = array( 'http'=>array( 'method'=>"POST", 'header'=> "Auth: SecretAuthTokenrn" . "Content-type: application/x-www-form-urlencodedrn" . "Content-length: " . strlen("Hello World"), 'content' => 'Hello World' ) ); $default = stream_context_get_default($opts); readfile('http://localhost/dev/streams/php_input.php');
首先要定义一个options array,这是个二位数组,可以通过$array['wrapper']['option_name']的形式来访问其中的参数。(注意每个包装类中context的options是不同的)。然后调用stream_context_get_default()来设置这些option,stream_context_get_default()同时还会将默认的context作为结果返回回来。设置完成后,接下来调用readfile(),就会应用刚才设置好的context来抓取内容。
在上面的例子中,内容被嵌入到request的body中,这样远端的脚本就可以使用php://input来读取这些内容。同时,我们还能使用apache_request_headers()来获取request的header,如下所示:
Array ( [Host] => localhost [Auth] => SecretAuthToken [Content-type] => application/x-www-form-urlencoded [Content-length] => 11 )
在上面的例子中是修改默认context的参数,当然我们也可以创建一个新的context,进行交替使用。
<?php $alternative = stream_context_create($other_opts); readfile('http://localhost/dev/streams/php_input.php', false, $alternative);
结论
我们怎样在现实世界中驾驭stream的强大力量呢?使用stream能为我们的程序带来什么现实的好处? 正如前文介绍的那样,stream对所有文件系统相关的功能进行了抽象,所以我第一个想到的应用场景是使用虚拟文件系统的包装类来访问PaaS供应商提供的服务,比如说访问HeroKu或者AppFog,它们实际上都没有真正文件系统。 使用stream只要对我们的应用程序稍作修改,就可以将其移植到云端。 接下来--在我的下一篇文章中--我将介绍如何编写自定义的包装类以实现对特殊文件格式和编码格式的操作。