PHP Conference Japan 2024

streamWrapper 類別

(PHP 4 >= 4.3.2, PHP 5, PHP 7, PHP 8)

簡介

允許您實作自己的協定處理程式和串流,以便與所有其他檔案系統函式(例如 fopen()fread() 等)一起使用。

注意:

這*不是*一個真正的類別,只是一個定義自己協定的類別的原型。

注意:

以與此處描述不同的方式實作這些方法可能會導致未定義的行為。

一旦串流函式嘗試存取與其關聯的協定,就會初始化此類別的實例。

類別概要

類別 streamWrapper {
/* 屬性 */
公開 資源 $context;
/* 方法 */
公開 __construct()
公開 dir_opendir(字串 $path, 整數 $options): 布林值
公開 mkdir(字串 $path, 整數 $mode, 整數 $options): 布林值
公開 rename(字串 $path_from, 字串 $path_to): 布林值
公開 rmdir(字串 $path, 整數 $options): 布林值
公開 stream_cast(整數 $cast_as): 資源
公開 stream_close():
公開 stream_lock(整數 $operation): 布林值
公開 stream_metadata(字串 $path, 整數 $option, 混合 $value): 布林值
公開 stream_open(
    字串 $path,
    字串 $mode,
    整數 $options,
    ?字串 &$opened_path
): 布林值
公開 stream_read(整數 $count): 字串|false
公開 stream_seek(整數 $offset, 整數 $whence = SEEK_SET): 布林值
公開 stream_set_option(整數 $option, 整數 $arg1, 整數 $arg2): 布林值
公開 stream_truncate(整數 $new_size): 布林值
公開 stream_write(字串 $data): 整數
公開 unlink(字串 $path): 布林值
公開 url_stat(字串 $path, 整數 $flags): 陣列|false
public __destruct()
}

屬性

resource context

目前的 脈絡 (context),如果沒有脈絡傳遞給呼叫者函數,則為 null

使用 stream_context_get_options() 來解析脈絡。

注意:

此屬性*必須*為公開,以便 PHP 可以使用實際的脈絡資源來填充它。

目錄

新增註釋

使用者貢獻的註釋 4 則註釋

isaac dot z dot no dot foster at spam dot gmail dot please dot com
14 年前
值得注意的是,由 yannick at gmail 定義的介面不應該總是透過串流包裝器類別來實作,因為如果類別不需要使用某些方法,則不應該實作它們(根據手冊)。

具體來說,如果包裝器不需要 mkdir、rename、rmdir 和 unlink 方法,則「不應定義」這些方法。如此一來,才不會傳回不適當的錯誤訊息。

如果實作了介面,就沒有不實作這些方法的彈性。

我不是想咬文嚼字,但这對我來說很有用。
info at ensostudio dot ru
4 年前
這些方法不是必需的,您可以只實作其中一部分:例如目錄、檔案等等。
例如,「glob://」支援最少的語法,glob() 功能更強大,您可以替換/擴充原生包裝器:在表格 https://php.dev.org.tw/manual/ru/wrappers.glob 中查看選項,您只需要使用 'dir_...dir' 方法建立包裝器。更多資訊請參閱 https://php.dev.org.tw/manual/en/class.globiterator.php#125220
匿名
13 年前
這是一個非常簡單的串流包裝器,它會在讀取時呼叫您的回呼函式。

<?php

class CallbackUrl
{
const
WRAPPER_NAME = 'callback';

public
$context;
private
$_cb;
private
$_eof = false;

private static
$_isRegistered = false;

public static function
getContext($cb)
{
if (!
self::$_isRegistered) {
stream_wrapper_register(self::WRAPPER_NAME, get_class());
self::$_isRegistered = true;
}
if (!
is_callable($cb)) return false;
return
stream_context_create(array(self::WRAPPER_NAME => array('cb' => $cb)));
}

public function
stream_open($path, $mode, $options, &$opened_path)
{
if (!
preg_match('/^r[bt]?$/', $mode) || !$this->context) return false;
$opt = stream_context_get_options($this->context);
if (!
is_array($opt[self::WRAPPER_NAME]) ||
!isset(
$opt[self::WRAPPER_NAME]['cb']) ||
!
is_callable($opt[self::WRAPPER_NAME]['cb'])) return false;
$this->_cb = $opt[self::WRAPPER_NAME]['cb'];
return
true;
}

public function
stream_read($count)
{
if (
$this->_eof || !$count) return '';
if ((
$s = call_user_func($this->_cb, $count)) == '') $this->_eof = true;
return
$s;
}

public function
stream_eof()
{
return
$this->_eof;
}
}

class
Test {
private
$_s;
public function
__construct($s)
{
$this->_s = $s;
}
public function
read($count) {
return
fread($this->_s, $count);
}
}

$t = new Test(fopen('/etc/services', 'r'));
$fd = fopen('callback://', 'r', false, CallbackUrl::getContext(array($t, 'read')));
while((
$buf = fread($fd, 128)) != '') {
print
$buf;
}
?>
yannick dot battail at gmail dot com
15 年前
包裝器的 PHP 介面

<?php
interface WrapperInterface
{
/**
* resource context
*
* @var resource
*/
//public $context;

/**
* constructor
*
*/
public function __construct();

/**
*
*
* @return bool
*/
public function dir_closedir();

/**
* Enter description here...
*
* @param string $path
* @param int $options
* @return bool
*/
public function dir_opendir($path , $options);

/**
* Enter description here...
*
* @return string
*/
public function dir_readdir();

/**
* Enter description here...
*
* @return bool
*/
public function dir_rewinddir();

/**
* Enter description here...
*
* @param string $path
* @param int $mode
* @param int $options
* @return bool
*/
public function mkdir($path , $mode , $options);

/**
* Enter description here...
*
* @param string $path_from
* @param string $path_to
* @return bool
*/
public function rename($path_from , $path_to);

/**
* Enter description here...
*
* @param string $path
* @param int $options
* @return bool
*/
public function rmdir($path , $options);

/**
* Enter description here...
*
* @param int $cast_as
* @return resource
*/
public function stream_cast($cast_as);

/**
* Enter description here...
*
*/
public function stream_close();

/**
* Enter description here...
*
* @return bool
*/
public function stream_eof();

/**
* Enter description here...
*
* @return bool
*/
public function stream_flush();

/**
* Enter description here...
*
* @param mode $operation
* @return bool
*/
public function stream_lock($operation);

/**
* Enter description here...
*
* @param string $path
* @param string $mode
* @param int $options
* @param string &$opened_path
* @return bool
*/
public function stream_open($path , $mode , $options , &$opened_path);

/**
* Enter description here...
*
* @param int $count
* @return string
*/
public function stream_read($count);

/**
* Enter description here...
*
* @param int $offset
* @param int $whence = SEEK_SET
* @return bool
*/
public function stream_seek($offset , $whence = SEEK_SET);

/**
* Enter description here...
*
* @param int $option
* @param int $arg1
* @param int $arg2
* @return bool
*/
public function stream_set_option($option , $arg1 , $arg2);

/**
* Enter description here...
*
* @return array
*/
public function stream_stat();

/**
* Enter description here...
*
* @return int
*/
public function stream_tell();

/**
* Enter description here...
*
* @param string $data
* @return int
*/
public function stream_write($data);

/**
* Enter description here...
*
* @param string $path
* @return bool
*/
public function unlink($path);

/**
* Enter description here...
*
* @param string $path
* @param int $flags
* @return array
*/
public function url_stat($path , $flags);
}

?>
To Top