導航:首頁 > 編程語言 > php解析文件流

php解析文件流

發布時間:2025-07-15 01:51:19

php流(Stream)的概述與使用詳解

在現代 PHP 特性中,流或許是最出色但使用率最低的。雖然 PHP 4.3 就引入了流,但是很多開發者並不知道流的存在,因為人們很少提及流,而且流的文檔也很匱乏。PHP 官方文檔對流的解釋如下:

可能看完這段解釋後還是雲里霧里,我們簡化一下,流的作用是在出發地和目的地之間傳輸數據。出發地和目的地可以是文件、命令行進程、網路連接、ZIP 或 TAR 壓縮文件、臨時內存、標准輸入或輸出,或者是通過 PHP 流封裝協議實現的任何其他資源。

如果你讀寫過文件,就用過流;如果你從 php://stdin 讀取過數據,或者把輸入寫入 php://stdout ,也用過流。流為 PHP 的很多 IO 函數提供了底層實現,如 file_get_contents、fopn、fread 和 fwrite 等。PHP 的流函數提供了不同資源的統一介面。

我們可以把流比作管道,把水(資源數據)從一個地方引到另一個地方。在水從出發地到目的地的過程中,我們可以過濾水,可以改變水質,可以添加水,也可以排出水。

流式數據的種類各異,每種類型需要獨特的協議,以便讀寫數據,我們稱這些協議為 流封裝協議 。例如,我們可以讀寫文件系統,可以通過 HTTP、HTTPS 或 SSH 與遠程 Web 伺服器通信,還可以打開並讀寫 ZIP、RAR 或 PHAR 壓縮文件。這些通信方式都包含下述相同的過程:

1.開始通信
2.讀取數據
3.寫入數據
4.結束通信

雖然過程是一樣的,但是讀寫文件系統中文件的方式與收發 HTTP 消息的方式有所不同,流封裝協議的作用是使用通用的介面封裝這種差異。

每個流都有一個協議和一個目標。指定協議和目標的方法是使用流標識符:<scheme>://<target>,其中 <scheme> 是流的封裝協議,<target> 是流的數據源。

http://流封裝協議

下面使用 HTTP 流封裝協議創建了一個與 Flicker API 通信的 PHP 流:

不要以為這是普通的網頁 URL,file_get_contents() 函數的字元串參數其實是一個流標識符。http 協議會讓 PHP 使用 HTTP 流封裝協議,在這個參數中,http 之後是流的目標。

我們通常使用 file_get_contents()、fopen()、fwrite() 和 fclose() 等函數讀寫文件系統,因為 PHP 默認使用的流封裝協議是 file://,所以我們很少認為這些函數使用的是 PHP 流。下面的示例演示了使用 file:// 流封裝協議創建一個讀寫 /etc/hosts 文件的流:

我們通常會省略掉 file:// 協議,因為這是 PHP 使用的默認值。

php://流封裝協議

編寫命令行腳本的 PHP 開發者會感激 php:// 流封裝協議,這個流封裝協議的作用是與 PHP 腳本的標准輸入、標准輸出和標准錯誤文件描述符通信。我們可以使用 PHP 提供的文件系統函數打開、讀取或寫入下面四個流:

1. php://stdin :這是個只讀 PHP 流,其中的數據來自標准輸入。PHP 腳本可以使用這個流接收命令行傳入腳本的信息;
2. php://stdout :把數據寫入當前的輸出緩沖區,這個流只能寫,無法讀或定址;
3. php://memory :從系統內存中讀取數據,或者把數據寫入系統內存。缺點是系統內存有限,所有使用 php://temp 更安全;
4. php://temp :和 php://memory 類似,不過,沒有可用內存時,PHP 會把數據寫入這個臨時文件。

其他流封裝協議

PHP 和 PHP 擴展還提供了很多其他流封裝協議,例如,與 ZIP 和 TAR 壓縮文件、FTP 伺服器、數據壓縮庫、Amazon API、Dropbox API 等通信的流封裝協議。需要注意的是,PHP 中的 fopen()、fgets()、fputs()、feof() 以及 fclose() 等函數不僅可以用來處理文件系統中的文件,還可以在所有支持這些函數的流封裝協議中使用。

自定義流封裝協議

我們還可以自己編寫 PHP 流封裝協議。PHP 提供了一個示例 StreamWrapper 類,演示如何編寫自定義的流封裝協議,支持部分或全部 PHP 文件系統函數。關於如何編寫,具體請參考以下文檔:

http://php.net/manual/zh/class.streamwrapper.php
http://php.net/manual/zh/stream.streamwrapper.example-1.php

有些 PHP 流能夠接受一系列可選的參數,這些參數叫流上下文,用於定製流的行為。不同的流封裝協議使用的流上下文有所不同,流上下文使用 stream_context_create() 函數創建,這個函數返回的上下文對象可以傳入大多數文件系統函數。

例如,你知道可以使用 file_get_contents() 發送 HTTP POST 請求嗎?使用一個流上下文對象即可實現:

流過濾器
目前為止我們討論了如何打開流,讀取流中的數據,以及把數據寫入流。不過,PHP 流真正強大的地方在於過濾、轉換、添加或刪除流中傳輸的數據,例如,我們可以打開一個流處理 Markdown 文件,在把文件內容讀入內存的過程中自動將其轉化為 HTML。

運行該腳本,輸出的都是大寫字母:

我們還可以使用 php://filter 流封裝協議把過濾器附加到流上,不過,使用這種方式之前必須先打開 PHP 流:

這個方式實現效果和 stream_filter_append() 函數一樣,但是相比之下更為繁瑣。不過,PHP 的某些文件系統函數在調用後無法附加過濾器,例如 file() 和 fpassthru(),使用這些函數時只能使用 php://filter 流封裝協議附加流過濾器。

自定義流過濾器
我們還可以編寫自定義的流過濾器。其實,大多數情況下都要使用自定義的流過濾器,自定義的流過濾器是個 PHP 類,繼承內置的 php_user_filter 類( http://php.net/manual/zh/class.php-user-filter.php ),且必須實現 filter()、onCreate() 和 onClose() 方法,最後,必須使用 stream_filter_register() 函數注冊自定義的流過濾器。

然後,我們必須使用 stream_filter_register() 函數注冊這個自定義的 DirtyWordsFilter 流過濾器:

第一個參數用於標識這個自定義過濾器的過濾器名,第二個參數是這個自定義過濾器的類名。接下來就可以使用這個自定義的流過濾器了:

修改 test.txt 內容如下:

運行上面的自定義過濾器腳本,結果如下:

stream_bucket_append函數:為隊列添加數據
stream_bucket_make_writeable函數:從操作的隊列中返回一個數據對象
stream_bucket_new函數:為當前隊列創建一個新的數據
stream_bucket_prepend函數:預備數據到隊列
stream_context_create函數:創建數據流上下文
stream_context_get_default函數:獲取默認的數據流上下文
stream_context_get_options函數:獲取數據流的設置
stream_context_set_option函數:對數據流、數據包或者上下文進行設置
stream_context_set_params函數:為數據流、數據包或者上下文設置參數
stream__to_stream函數:在數據流之間進行復制操作
stream_filter_append函數:為數據流添加過濾器
stream_filter_prepend函數:為數據流預備添加過濾器
stream_filter_register函數:注冊一個數據流的過濾器並作為PHP類執行
stream_filter_remove函數:從一個數據流中移除過濾器
stream_get_contents函數:讀取數據流中的剩餘數據到字元串
stream_get_filters函數:返回已經注冊的數據流過濾器列表
stream_get_line函數:按照給定的定界符從數據流資源中獲取行
stream_get_meta_data函數:從封裝協議文件指針中獲取報頭/元數據
stream_get_transports函數:返回注冊的Socket傳輸列表
stream_get_wrappers函數:返回注冊的數據流列表
stream_register_wrapper函數:注冊一個用PHP類實現的URL封裝協議
stream_select函數:接收數據流數組並等待它們狀態的改變
stream_set_blocking函數:將一個數據流設置為堵塞或者非堵塞狀態
stream_set_timeout函數:對數據流進行超時設置
stream_set_write_buffer函數:為數據流設置緩沖區
stream_socket_accept函數:接受由函數stream_ socket_server()創建的Socket連接
stream_socket_client函數:打開網路或者UNIX主機的Socket連接
stream_socket_enable_crypto函數:為一個已經連接的Socket打開或者關閉數據加密
stream_socket_get_name函數:獲取本地或者網路Socket的名稱
stream_socket_pair函數:創建兩個無區別的Socket數據流連接
stream_socket_recvfrom函數:從Socket獲取數據,不管其連接與否
stream_socket_sendto函數:向Socket發送數據,不管其連接與否
stream_socket_server函數:創建一個網路或者UNIX Socket服務端
stream_wrapper_restore函數:恢復一個事先注銷的數據包
stream_wrapper_unregister函數:注銷一個URL地址包

整合資料
本文整合於以下兩篇文章

https://blog.csdn.net/qq756684177/article/details/81518647

https://xueyuanjun.com/post/7459.html

Ⅱ php如何將圖片轉成位元組流

在php中,有文件上傳,那麼php伺服器端可以接收到請求參數 $_FILES,在 $_FILES數組中讀取到上傳文件的form表單名,然後在讀取的數組中可以獲取上傳文件的源文件,使用 fopen()函數就可以獲取文件的位元組流了。
具體來點代碼看看吧:(假定上傳文件的表單名為 「formname」)
if($_FILES && isset($_FILES["formname"])){
//獲取上傳的文件的屬性數組
$_fileinfo = $_FILES["formname"];
//獲取上傳文件的原文件名
$_filename = $_fileinfo["name"];
//獲取上傳文件的大小
$_filesize = $_fileinfo["size"];
//獲取上傳文件的臨時文件名(長文件名)
$_filesource = $_fileinfo["tmp_name"];
//以讀寫方式打開文件,並將資源綁定到一個流上
$_filestream = fopen($_filesource,"ab");
//實現上傳文件,其實質是把臨時文件移動到制定的保存文件的位置
$_newfilename = "../mypath/filename.exp"; //自定義文件名,包含路徑,可以是相對路徑
move_uploaded_file($_filesource, $_newfilename);
}

Ⅲ php 獲得當前文件輸出流

首先你要了解幾個php函數,下面我列出來

ob_start()函數:打開輸出緩沖區.
函數格式 void ob_start(void)
說明:當緩沖區激活時,所有來自PHP程序的非文件頭信息均不會發送,而是保存在內部緩沖區。為了輸出緩沖區的內容,可以使用ob_end_flush()或flush()輸出緩沖區的內容。

Flush:刷新緩沖區的內容,輸出。
函數格式:flush()
說明:這個函數經常使用,效率很高。

ob_get_contents :返回內部緩沖區的內容。
函數格式:string ob_get_contents(void)
說明:這個函數會返回當前緩沖區中的內容,如果輸出緩沖區沒有激活,則返回 FALSE.

ob_get_length:返回內部緩沖區的長度。
函數格式:int ob_get_length(void)
說明:這個函數會返回當前緩沖區中的長度;和ob_get_contents一樣,如果輸出緩沖區沒有激活,則返回 FALSE.

ob_end_clean:刪除內部緩沖區的內容,並且關閉內部緩沖區
函數格式:void ob_end_clean(void)
說明:這個函數不會輸出內部緩沖區的內容而是把它刪除

ob_end_flush:發送內部緩沖區的內容到瀏覽器,並且關閉輸出緩沖區
函數格式:void ob_end_flush(void)
說明:這個函數發送輸出緩沖區的內容(如果有的話)

ob_implicit_flush:打開或關閉絕對刷新
函數格式:void ob_implicit_flush ([int flag])
說明:默認為關閉緩沖區,打開絕對輸出後,每個腳本輸出都直接發送到瀏覽器,不再需要調用 flush()

是的,正如你看到的,就是利用php緩沖區,當你用ob_start()打開緩沖區的話,則你接下來的輸出,在不會輸出到瀏覽器,而是被緩存到內存上,知道內存被通知輸出獲取處理是,才會有所行動,這樣的話,你完全可以

Ⅳ 請問各位大神, PHP怎麼獲取FLV文件的寬和高, 還有請問如果獲取MP4文件的時長和寬高

對於FLV文件的寬和高,通常需要藉助第三方解碼庫獲取,比如使用FFmpeg,它可以解析FLV文件,提取出視頻的尺寸等元數據。安裝FFmpeg後,可以使用命令行或者編寫腳本來調用FFmpeg,通過輸入FLV文件路徑,獲取到視頻的寬度和高度。

同樣地,對於MP4文件,也需要藉助FFmpeg來獲取其時長和寬高信息。安裝FFmpeg之後,可以編寫腳本調用FFmpeg,通過提供MP4文件路徑,FFmpeg會返回視頻的解析度(寬和高)以及總時長。具體來說,可以使用FFmpeg的「-i」選項來指定輸入文件,然後通過解析FFmpeg命令執行後的輸出結果,來獲取所需的視頻信息。

以獲取MP4視頻的寬高為例,命令行可以使用如下格式:ffmpeg -i input.mp4 2>&1 | grep 'Duration' -A 1 | grep 'Stream' -A 1 | grep 'Video' -A 1 | awk -F '[ =:]' '{print $3}'。這段命令會輸出視頻的寬度和高度。同樣地,獲取時長的信息,則可以通過「Duration」欄位來獲取,比如使用「ffmpeg -i input.mp4 2>&1 | grep 'Duration'」來提取。

需要注意的是,FFmpeg的版本更新頻繁,不同版本可能會有不同的輸出格式,因此在編寫腳本時,需要根據實際情況調整命令和解析方式。另外,對於在線視頻或流媒體,由於數據流不斷變化,可能需要使用其他工具或API來獲取實時的視頻信息。

在實際應用中,除了直接調用FFmpeg命令,還可以通過編程語言(如PHP)封裝FFmpeg的介面,以更方便地獲取視頻信息。例如,在PHP中,可以使用exec()或shell_exec()函數來執行FFmpeg命令,並通過解析命令的輸出來獲取所需的信息。這種方式不僅提高了代碼的可讀性和可維護性,還簡化了視頻信息獲取的過程。

總之,獲取FLV或MP4文件的寬高和時長信息,主要依賴於第三方解碼庫,如FFmpeg。通過合理地使用這些工具和編程方法,可以輕松地實現視頻信息的自動化提取和處理。

Ⅳ 請問通過介面返回的pdf的文件流,怎麼用php把這些文件流轉為pdf文件

直接將文件流內容寫入文件,而文件的後綴名設為 pdf 格式就可以了;PHP 不管保存文件流還是文本,都是用這種方式;

$path="demo.pdf";
$ret=file_put_contents($path,$arr['data']);
if($ret){
echo'保存成功';//然後可以取查看文件
}

Ⅵ PHP關於獲取二進制數據流轉換為文件的方法

$content=$_POST['data'];
$fp=fopen('/tmp/newfile.bin','w');
fwrite($fp,$content);

以上例子是在data參數上傳二進制,並保存到/tmp/newfile.bin中,解析json用json_decode,然後把二進制的那個值賦給content就可以

閱讀全文

與php解析文件流相關的資料

熱點內容
為什麼安卓手機比蘋果耐寒 瀏覽:718
滴滴出行app什麼時候恢復正常下載 瀏覽:560
python中turtle繪制圖形並保存 瀏覽:565
php獲取上個月時間戳 瀏覽:574
怎麼設置oppo手機app密碼 瀏覽:360
jra格式下載哪個文件夾 瀏覽:658
蘋果手機怎麼刪除手機上的app 瀏覽:343
單片機熱敏電阻溫度控制 瀏覽:82
方舟私人伺服器的服主怎麼刷物資 瀏覽:454
重裝系統提示加密鎖 瀏覽:625
為什麼下載的音樂要加密 瀏覽:964
因為沒有打開的文檔所以這一命令無效 瀏覽:720
電腦文件夾數據損壞 瀏覽:716
java打賞源碼搭建 瀏覽:365
pdf32 瀏覽:256
植發加密100天效果 瀏覽:959
離心壓縮機檢修規程 瀏覽:432
如何收聽安卓手機發來的鏈接 瀏覽:401
福建微法院app怎麼用 瀏覽:210
android陀螺儀應用 瀏覽:721