Here is a very simple stream wrapper which calls your callback function for reads:
<?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;
}
?>
streamWrapper クラス
(バージョン情報なし。おそらく SVN 版にしか存在しないでしょう)
導入
独自のプロトコルハンドラやストリームを実装し、 (fopen() や fread() などの) 他のファイルシステム関数で使用できるようにします。
注意:
これは、実際のクラスではありません。 クラスがどのようにプロトコルを定義すべきかを示す、単なるプロトタイプです。
注意:
ここに示す方法以外でメソッドを実装した場合の挙動は未定義となります。
このクラスのインスタンスは、 関連付けられているプロトコルへのストリーム関数からのアクセスがあった時点で初期化されます。
クラス概要
streamWrapper
{
/* プロパティ */
/* メソッド */
streamWrapper::__construct
( void
)
streamWrapper::__destruct
( void
)
public bool streamWrapper::stream_open
( string $path
, string $mode
, int $options
, string &$opened_path
)
}プロパティ
- resource context
-
現在のコンテキスト、 あるいは呼び出し元からコンテキストが渡されていない場合は NULL。
stream_context_get_options() を用いてコンテキストをパースします。
注意:
このプロパティは必ず public とし、 PHP が実際のコンテキストリソースを設定できるようにしなければなりません。
変更履歴
| バージョン | 説明 |
|---|---|
| 5.0.0 | context プロパティが追加されました。 |
目次
- streamWrapper::__construct — 新しいストリームラッパーを作成する
- streamWrapper::__destruct — 既存のストリームラッパーを破棄する
- streamWrapper::dir_closedir — ディレクトリハンドルを閉じる
- streamWrapper::dir_opendir — ディレクトリハンドルをオープンする
- streamWrapper::dir_readdir — ディレクトリハンドルからエントリを読み込む
- streamWrapper::dir_rewinddir — ディレクトリハンドルを巻き戻す
- streamWrapper::mkdir — ディレクトリを作成する
- streamWrapper::rename — ファイルあるいはディレクトリの名前を変える
- streamWrapper::rmdir — ディレクトリを削除する
- streamWrapper::stream_cast — 元となるリソースを取得する
- streamWrapper::stream_close — リソースを閉じる
- streamWrapper::stream_eof — ファイルポインタが終端にあるかどうかを調べる
- streamWrapper::stream_flush — 出力をフラッシュする
- streamWrapper::stream_lock — ファイルのアドバイザリ・ロック
- streamWrapper::stream_metadata — ストリームオプションを変更する
- streamWrapper::stream_open — ファイルあるいは URL をオープンする
- streamWrapper::stream_read — ストリームから読み込む
- streamWrapper::stream_seek — ストリーム内の特定の場所に移動する
- streamWrapper::stream_set_option — ストリームのオプションを変更する
- streamWrapper::stream_stat — ファイルリソースについての情報を取得する
- streamWrapper::stream_tell — ストリームの現在位置を取得する
- streamWrapper::stream_write — ストリームに書き込む
- streamWrapper::unlink — ファイルを削除する
- streamWrapper::url_stat — ファイルについての情報を取得する
Anonymous
21-Sep-2011 12:02
isaac dot z dot no dot foster at spam dot gmail dot please dot com
22-Oct-2010 09:12
It's worth noting that the interface defined by yannick at gmail should not always be implemented by a stream wrapper class, as several of the methods should not be implemented if the class has no use for them (as per the manual).
Specifically, mkdir, rename, rmdir, and unlink are methods that "should not be defined" if the wrapper has no use for them. The consequence is that the appropriate error message will not be returned.
If the interface is implemented, you won't have the flexibility to not implement those methods.
Not trying to be academic, but it was useful for me.
yannick dot battail at gmail dot com
17-Jul-2009 02:38
a php interface for wrapper
<?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);
}
?>
