使用自定义流包装器作为PHP的http://流包装器的测试存根

发布时间:2022-04-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了使用自定义流包装器作为PHP的http://流包装器的测试存根脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_304_0@ 我正在编写一个自定义流包装器,用作使用内置http://流包装器的HTTP客户端类的单元测试中的存根.

具体来说,我需要通过调用自定义流包装器创建的流上的stream_get_Meta_data来控制’wrapPEr_data’键中返回的值.不幸的是,关于自定义流包装器的文档很糟糕,API似乎不直观.

自定义包装器中的哪个方法控制Meta wrapper_data响应?

使用底部的类我只能在var_dump(stream_get_Meta_data($stream))时得到以下结果;在使用自定义包装器创建的流上…

array(10) {
  'wrapper_data' =>
  class CustomHttpStreamWrapper#5 (3) {
    public $context =>
    resource(13) of type (stream-context)
    public $posITion =>
    int(0)
    public $bodyData =>
    string(14) "test body data"
  }
  ...

但我需要哄骗包装器在元数据检索上产生类似下面的内容,这样我就可以测试客户端类对真实http://流包装器返回的数据的解析…

array(10) {
  'wrapper_data' => Array(
       [0] => HTTP/1.1 200 OK
       [1] => Content-Length: 438
   )
   ...

这是我目前用于自定义包装器的代码

class CustomHttpStreamWrapper {

    public $context;
    public $position = 0;
    public $bodyData = 'test body data';

    public function stream_open($path,$mode,$options,&$opened_path) {
        return true;
    }

    public function stream_read($count) {
        $this->position += strlen($this->bodyData);
        if ($this->position > strlen($this->bodyData)) {
            return false;
        }
        return $this->bodyData;
    }

    public function stream_eof() {
        return $this->position >= strlen($this->bodyData);
    }

    public function stream_stat() {
        return array('wrapper_data' => array('test'));
    }

    public function stream_tell() {
        return $this->position;
    }
}
stream_get_Meta_data在 ext/standard/streamfunc.c中实现.相关部分是
if (stream->wrapperdata) {
    MAKE_STD_ZVAL(newval);
    MAKE_COPY_ZVAL(&stream->wrapperdata,newval);

    add_assoc_zval(return_value,"wrapper_data",newval);
}

即,任何zval流 – > wrapperdata保持被$retval [“wrapper_data”]“复制”/引用.
您的自定义包装器代码由user_wrapper_opener在main/streams/userspace.c“处理”.您有

/* set wrapper data to be a reference to our object */
stream->wrapperdata = us->object;

us-> object“is”已为流实例化的自定义包装器的实例.我还没有找到一种方法来影响来自其他用户空间脚本的stream-> wrapperdata.
但是你可以实现Iterator/IteratorAggregate和/或ArrayAccess,如果你需要的只是foreach($Metadata [‘wrapper_data’] …)和$Metadata [‘wrapper_data’] [$i].
例如.

<?PHP
function test() {
    stream_wrapper_register("mock","CustomHttpStreamWrapper") or die("Failed to register PRotocol");
    $fp = fopen("mock://myVAR","r+");
    $md = stream_get_Meta_data($fp);

    echo "Iterator / IteratorAggregate\n";
    foreach($md['wrapper_data'] as $e) {
        echo $e,"\n";
    }

    echo "\nArrayAccess\n";
    echo $md['wrapper_data'][0],"\n";

    echo "\nvar_dump\n";
    echo var_dump($md['wrapper_data']);
}

class CustomHttpStreamWrapper implements IteratorAggregate,ArrayAccess  {
    public $context;
    public $position = 0;
    public $bodyData = 'test body data';

    protected $foo = array('HTTP/1.1 200 OK','Content-Length: 438','foo: bar','ham: eggs');
    /* IteratorAggregate */
    public function getIterator() {
        return new ArrayIterator($this->foo);
    }
    /* ArrayAccess */
    public function offsetExists($offset) { return array_key_exists($offset,$this->foo); }
    public function offsetGet($offset ) { return $this->foo[$offset]; }
    public function offsetSet($offset,$value) { $this->foo[$offset] = $value; }
    public function offsetUnset($offset) { unset($this->foo[$offset]); }

    /* StreamWrapper */
    public function stream_open($path,&$opened_path) {
        return true;
    }

    public function stream_read($count) {
        $this->position += strlen($this->bodyData);
        if ($this->position > strlen($this->bodyData)) {
            return false;
        }
        return $this->bodyData;
    }

    public function stream_eof() {
        return $this->position >= strlen($this->bodyData);
    }

    public function stream_stat() {
        return array('wrapper_data' => array('test'));
    }

    public function stream_tell() {
        return $this->position;
    }
}

test();

版画

Iterator / IteratorAggregate
HTTP/1.1 200 OK
Content-Length: 438
foo: bar
ham: eggs

ArrayAccess
HTTP/1.1 200 OK

var_dump
object(CustomHttpStreamWrapper)#1 (4) {
  ["context"]=>
  resource(5) of type (stream-context)
  ["position"]=>
  int(0)
  ["bodyData"]=>
  string(14) "test body data"
  ["foo":protected]=>
  array(4) {
    [0]=>
    string(15) "HTTP/1.1 200 OK"
    [1]=>
    string(19) "Content-Length: 438"
    [2]=>
    string(8) "foo: bar"
    [3]=>
    string(9) "ham: eggs"
  }
}

脚本宝典总结

以上是脚本宝典为你收集整理的使用自定义流包装器作为PHP的http://流包装器的测试存根全部内容,希望文章能够帮你解决使用自定义流包装器作为PHP的http://流包装器的测试存根所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。