Merge pull request #9 from rullzer/enh/add_preClose_callback

Add a preClose callback
This commit is contained in:
Robin Appelman 2019-02-14 16:43:18 +01:00 committed by GitHub
commit e1b5ac12e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 4 deletions

View file

@ -44,6 +44,11 @@ class CallbackWrapper extends Wrapper {
*/
protected $readDirCallBack;
/**
* @var callable
*/
protected $preCloseCallback;
/**
* Wraps a stream with the provided callbacks
*
@ -56,14 +61,15 @@ class CallbackWrapper extends Wrapper {
*
* @throws \BadMethodCallException
*/
public static function wrap($source, $read = null, $write = null, $close = null, $readDir = null) {
public static function wrap($source, $read = null, $write = null, $close = null, $readDir = null, $preClose = null) {
$context = stream_context_create(array(
'callback' => array(
'source' => $source,
'read' => $read,
'write' => $write,
'close' => $close,
'readDir' => $readDir
'readDir' => $readDir,
'preClose' => $preClose,
)
));
return Wrapper::wrapSource($source, $context, 'callback', '\Icewind\Streams\CallbackWrapper');
@ -76,6 +82,7 @@ class CallbackWrapper extends Wrapper {
$this->writeCallback = $context['write'];
$this->closeCallback = $context['close'];
$this->readDirCallBack = $context['readDir'];
$this->preCloseCallback = $context['preClose'];
return true;
}
@ -104,6 +111,11 @@ class CallbackWrapper extends Wrapper {
}
public function stream_close() {
if (is_callable($this->preCloseCallback)) {
call_user_func($this->preCloseCallback, $this->loadContext('callback')['source']);
// prevent further calls by potential PHP 7 GC ghosts
$this->preCloseCallback = null;
}
$result = parent::stream_close();
if (is_callable($this->closeCallback)) {
call_user_func($this->closeCallback);

View file

@ -15,10 +15,11 @@ class CallbackWrapperTest extends WrapperTest {
* @param callable $write
* @param callable $close
* @param callable $readDir
* @param callable $preClose
* @return resource
*/
protected function wrapSource($source, $read = null, $write = null, $close = null, $readDir = null) {
return \Icewind\Streams\CallbackWrapper::wrap($source, $read, $write, $close, $readDir);
protected function wrapSource($source, $read = null, $write = null, $close = null, $readDir = null, $preClose = null) {
return \Icewind\Streams\CallbackWrapper::wrap($source, $read, $write, $close, $readDir, $preClose);
}
/**
@ -83,4 +84,21 @@ class CallbackWrapperTest extends WrapperTest {
readdir($wrapped);
$this->assertTrue($called);
}
public function testPreCloseCallback() {
$called = false;
$source = fopen('php://temp', 'r+');
fwrite($source, 'foobar');
rewind($source);
$callBack = function ($stream) use (&$called, $source) {
$called = true;
$this->assertSame($stream, $source);
};
$wrapped = $this->wrapSource($source, null, null, null, null, $callBack);
fclose($wrapped);
$this->assertTrue($called);
}
}