在昨天的文章中,我們對如何使用 Stream 這個 Feature 的使用方式做了一些說明。
事實上,除了使用官方預提供的 Stream 以外,我們仍然可以自定義 Stream 的實現。
舉例來說,我們甚至可以實現 dropbox://
或 s3://
這樣的 stream 然後加以利用(不過大多數的 Object Storage 都是提供 RESTful API 或是 SDK 去存取,罕有人會親自去實現 stream)
PHP 官方有提供一個範例,讓人可以參考如何實現自定義的 Stream Wrapper。
因為程式碼已經相當完整,所以這邊不重新複製貼上,僅針對程式碼本身做一些說明。
stream_open
stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool
用於開啟 stream,假設已經實現 dropbox://
且調用 fopen('dropbox://file.txt', 'r')
$path === 'dropbox://file.txt'
$mode === 'r'
$options === 0
$opened_path === 'dropbox://file.txt'
$options
具有兩個 flag:STREAM_USE_PATH
及 STREAM_REPORT_ERRORS
$opened_path
表示如果成功將 $path
指定的資源打開,會回傳與 $path
相同的內容,可用於檢測資源是否成功開啟。
註:
$mode
是可以自由定義的,不一定侷限於 file stream 的形式。
stream_read
stream_read(int $count): mixed
用於讀取指定的 stream,通常 $count
指的是「第幾個 byte」,不過這邊的定義可由實現者自行決定。
stream_write
stream_write(mixed $data): int
將 $data
寫入目前 stream 的所在位置,並且回傳成功寫入的資料長度.
stream_tell
stream_tell(): int
回傳目前 Stream 的所在位置,部份 Stream 都是可以任意操作位置的,此時利用 stream_tell
取得目前所在位置。
stream_eof
stream_eof(): bool
確認目前的 Stream 是否已經到盡頭,EOF 表示 End Of File,不過在 Stream 上依然能夠套用這樣的邏輯。
stream_seek
stream_seek(int $offset, int $whence): bool
用於在 Stream 中自由移動,$offset
表示移動「多少」資料(通常指的是 byte 數),$whence
則是來自於 C 語言的 fseek()
。
$whence
有三種可能的值:SEEK_SET
, SEEK_CUR
與 SEEK_END
,分別表示「從資料的開頭」、「從目前的位置」及「從資料的尾端」(不過你依然可以自由定義其它的可能值)
stream_metadata
stream_metadata(string $path, string $option, mixed $var): bool
用於變更目前使用 Stream 的 Metadata,通常是由以下函式呼叫時會使用的
touch()
chmod()
chown()
chgrp()
$path
與 stream_open
相同。
$option
可能是下列一個值:STREAM_META_TOUCH
, STREAM_META_OWNER_NAME
, STREAM_META_OWNER
, STREAM_META_GROUP_NAME
, STREAM_META_GROUP
及 STREAM_META_ACCESS
$var
根據 $option
的不同而有不同的值。
事實上, Stream 的實作時還是相當以 File 為本位進行思考,畢竟在 Linux 「萬物皆檔案」的思想中,Stream 也是一種檔案流。
通常不太會自行實現網路服務相關的 Stream,僅會針對一些比較底層的服務(如 NFS)設計一些 stream 來使用,而這在實務上比較罕見(通常都是倚賴 RESTful API 去存取較多)