Add a preClose callback

This is useful in case a callback wants to do something with the stream
right before it gets closed.

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
This commit is contained in:
Roeland Jago Douma 2019-02-14 16:29:33 +01:00
commit 3c98a7556b
No known key found for this signature in database
GPG key ID: F941078878347C0C

View file

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