標籤:php steam
和SPL一樣,在PHP手冊裡面,流被劃為“other basic extensions”裡面,是PHP開發中一個容易被忽視的函數系列。但其實在C++/Java中,流是一個很重要的概念。流的概念源於UNIX中的管道,管道是一條不間斷的位元組流,用來實現程式和處理序間通訊,或者讀寫外設,外部檔案等。
流的概念是在php 4.3.0中被引入的。我們知道,檔案操作,網路操作,資料壓縮操作等具有一定的共性,比如線性讀/寫或者隨機定位,流就是用來把這些操作抽象出一個統一的介面以供開發人員們使用,因此“流”被定義為a resource object which exhibits streamable behavior。
當然,我們可以對stream進行進一步的封裝(wrapper),這樣就可以handle一些特定的協議。例如http wrapper可以把一個url翻譯成對遠程伺服器上檔案的HTTP/1.0請求。PHP預設已經實現了很多wrappers,可以用過stream_get_wrappers()來得到這個列表
stream wrapper的好處是使得開發人員使用統一的介面來開啟一個像URL,FTP之類的串連,而不需要關心協議的內容,除非自己實現一個php wrapper。
當然,除了這些內建的php stream wrappers以外,我們可以增加自訂的流,添加的方式有兩種
- 通過php指令碼stream_wrapper_register()來實現
- 通過調用php stream API來編寫C擴充實現。
流的使用方式為scheme://target,其中 scheme為wrapper的名稱(例如http),target取決於一個具體的stream.
那麼php stream到底有哪些應用情境呢?
task: 將一個用BZ2格式壓縮的檔案,將其編碼格式從ISO-8859-1轉至UTF-8,將全文轉成大寫,然後進行ROT-13編碼,再寫入一個新的檔案。
如果對php stream有簡要的瞭解以後,這個任務會非常容易
<?php/** * Example of stream filtering. */// Open two file handles.$in = fopen(‘test.txt.bz2‘, ‘rb‘);$out = fopen(‘test-uppercase.txt‘, ‘wb‘);// Add a decode filter to the first.stream_filter_prepend($in, ‘bzip2.decompress‘, STREAM_FILTER_READ);// Change the charset from ISO-8859-1 to UTF-8stream_filter_append($out, ‘convert.iconv.ISO-8859-1/UTF-8‘, STREAM_FILTER_WRITE);// Uppercase the entire string.stream_filter_append($out, ‘string.toupper‘, STREAM_FILTER_WRITE);// Run ROT-13 on the output.stream_filter_append($out, ‘string.rot13‘, STREAM_FILTER_WRITE);// Now copy. All of the filters are applied here.stream_copy_to_stream($in, $out);// Clean up.fclose($in);fclose($out);?>
這是因為php stream中一個特性-filter,其可以對流按照想要的方式進行過濾。php有一些內建的過濾器,可以通過stream_get_filters()來查看
當然,stream wrapper也提供了API讓開發人員自己開發一些filter。