关于hprose客户端传入集合对象变成数组解析

为什么会变成数组

是hprose默认帮我们处理做了转换


转换的规则

当你的参数里面带有对象时,hprose会有下面几个判断

vendor/hprose/hprose/src/Hprose/Writer.php:102

elseif (is_object($val)) {
    if ($val instanceof BytesIO) {
        $this->writeBytesIOWithRef($val);
    }
    elseif ($val instanceof DateTime) {
        $this->writeDateTimeWithRef($val);
    }
    elseif ($val instanceof SplObjectStorage) {
        $this->writeMapWithRef($val);
    }
    elseif ($val instanceof Traversable) {
        $this->writeListWithRef($val);
    }
    elseif ($val instanceof stdClass) {
        $this->writeStdClassWithRef($val);
    }
    else {
        $this->writeObjectWithRef($val);
    }
}
复制代码

我们的的Collection集合对象,属于第四种情况$val instanceof Traversable

这是因为我们的Collection集合类实现了IteratorAggregate接口,而IteratorAggregate又继承了Traversable接口

class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate, Jsonable, JsonSerializable复制代码


writeListWithRef的实现

vendor/hprose/hprose/src/Hprose/Writer.php:257

public function writeListWithRef(Traversable $list) {
    if (!$this->refer->write($this->stream, $list)) {
        // 直接到这里,调用了这个方法也就默认使用数组去处理
        $this->writeList($list);
    }
}复制代码

tips: RealWriterRefer依赖SplObjectStorage实现了引用的存储,这样以来如果重复传输参数可以减少传输字节数

writeList的实现

public function writeList(Traversable $list) {
    $this->refer->set($list);
    $count = count($list);
    $this->stream->write(Tags::TagList);
    if ($count > 0) {
        $this->stream->write((string)$count);
    }
    $this->stream->write(Tags::TagOpenbrace);
    // 这里是迭代取值
    foreach ($list as $e) {
        $this->serialize($e);
    }
    $this->stream->write(Tags::TagClosebrace);
}复制代码

最终collect([1, 2, 3])  => 序列化之后变成 a3{123}}


疑问:为什么服务端传过来的Collection,为什么客户端没有变成array

因为客户端的app/LaravelClient.php里面有一层关于数组的处理,默认把数组转换为集合对象


应该怎样正确传对象参数

结合上面判断条件

1、BytesIO 对象

参考:vendor/hprose/hprose/src/Hprose/BytesIO.php

作用:等同于直接传字符串

例: new BytesIO('hello world, 你好,世界') => b28"hello world, 你好,世界"

2、DateTime

作用:传入日期对象

例:new \DateTime() => D20180710T161744.000000;

服务端可解析为对象

DateTime {#2207
    +"date": "2018-07-10 14:45:55.000000"
    +"timezone_type": 3
    +"timezone": "PRC"
}复制代码

3、SplObjectStorage

4、.....

有兴趣的同学自行研究吧?



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值