V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
LeeLou
V2EX  ›  PHP

请教关于 PHP 的 json_encode 问题,是不是它的格式跟 Python , Java 生成的有些不一样?

  •  
  •   LeeLou · 2019-06-23 09:07:12 +08:00 · 4673 次点击
    这是一个创建于 1983 天前的主题,其中的信息可能已经有所发展或是发生改变。
    以下是一个 soap 的接口,往该接口的 funMain 方法上,传输一个 json,就可以发送短信了。这个是 php 的代码,显示失败
    $url = 'http://***/wsApi?wsdl';
    $content=’ this is a test message';
    $funcode = '1002'; //自定义扩展代码(模块)
    $ApplicationID = 'HsqjSYsn6QjTrqzdW'; //账号
    $Password = '6VnLZlVwKf'; //密码
    $paras = array(
    'content' =>$content,
    'funCode' =>$funcode,
    'applicationId' =>$ApplicationID,
    'password' =>$Password);

    $sendInfo=array(
    'sendId' =>'0',
    'mobile' =>'18899990000'); //手机号码
    $paras['sendInfo'] ][0]=$sendInfo;
    $client = new soapclient($url);
    $result=$client->funMain(json_encode($paras));

    而用 python,是没有问题的。
    import sys
    import json
    import suds

    from suds.client import Client

    url='http://***/wsApi?wsdl'
    c=Client(url)

    def sms(phonenumber,text):

    data={\
    'applicationId': 'HsqjSYsn6QjTrqzdW5K',\
    'password': '6VnLZlVw',\
    'funCode': '1002',\
    'content': 'this is for what you want to sent',\
    'sendInfo': [\
    {\
    'sendId': '0',\
    'mobile': '188990000'\
    }\
    ]\
    }



    data['content']=text
    data['sendInfo'][0]['mobile']=phonenumber
    d=json.dumps(data)


    e=c.service.funMain(d)






    if __name__=='__main__':

    if len(sys.argv)!=3:

    print ('Usage:python need 2 string')

    exit(1)

    phonenumber=sys.argv[1]

    text=sys.argv[2]

    try:

    sms(phonenumber,text)
    except:
    print ('duanxinji failure')
    第 1 条附言  ·  2019-07-01 16:39:22 +08:00
    ______________________________我是分割线,最终是可以发送短信了——————————
    最后用 soapUI 软件查了一下 webservice 的请求格式,是这样的。
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="ws.***.com">
    <soapenv:Header/>
    <soapenv:Body>
    <ws:funMain>
    <!--Optional:-->
    <arg0>?</arg0>
    </ws:funMain>
    </soapenv:Body>
    </soapenv:Envelope>

    然后我在 php 里用 funMain(array('arg0'=>json_encode($paras))就可以了,就是不知道在 python 的 suds 为什么不需要 arg0, 以后碰到这样的问题,是不是需要用抓包工具来看一下 webservice 的请求包?
    22 条回复    2019-06-25 21:02:06 +08:00
    rickygao
        1
    rickygao  
       2019-06-23 09:10:21 +08:00 via Android
    你自己把 json 打印出来比较一下不就完了,还至于来这问
    wangsongyan
        2
    wangsongyan  
       2019-06-23 09:15:22 +08:00 via iPhone
    不懂 PHP,不过 data 是 object,不是 array
    LeeLou
        3
    LeeLou  
    OP
       2019-06-23 09:15:42 +08:00
    @rickygao ,打印出来看过,其实看不出任何区别。我还把 python 那边打印出来的字符串,直接输入 php 里作为字符串,提交了还是不对,难道是我用的函数方法不对吗? 但是返回代码的格式却是一模一样的
    wangsongyan
        4
    wangsongyan  
       2019-06-23 09:28:47 +08:00 via iPhone
    @wangsongyan sorry,查了下不是这个问题。比较下生成的 json 字符串吧
    RobinT9
        5
    RobinT9  
       2019-06-23 09:30:28 +08:00 via iPhone
    想看你 py 成功的字符串
    Trim21
        6
    Trim21  
       2019-06-23 09:32:31 +08:00 via iPhone
    $paras['sendInfo'] ][0]=$sendInfo;
    Trim21
        7
    Trim21  
       2019-06-23 09:34:00 +08:00 via iPhone
    而且上面下面的手机号也不一样…生成的 json 真的一样吗
    oott123
        8
    oott123  
       2019-06-23 11:52:44 +08:00 via Android   ❤️ 1
    你都把 python 的 json 放到 php 里都不对,还在怀疑 json ?不应该调查下发请求的方法吗?
    LeeLou
        9
    LeeLou  
    OP
       2019-06-23 12:46:22 +08:00
    @Trim21 手机号只是一个比方,并没有把真的手机号发出来。
    @oott123 对 php 不了解,不知道怎么查发请求的方法对不对了,但有回应,而且请求的方法也一样,不应该有问题把
    @RobinT9 错误返回码如下:
    stdClass Object
    (
    [return] => <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <data>
    <batchId></batchId>
    <response/>
    <resultCode>1</resultCode>
    <resultMsg></resultMsg>
    </data>

    )
    wo642436249
        10
    wo642436249  
       2019-06-23 13:22:58 +08:00 via Android
    生成的是一个 json 字符串
    garlics
        11
    garlics  
       2019-06-23 13:25:52 +08:00 via Android
    你看下 funMain 这个方法参数需要传的是字符串还是数组
    Foctee
        12
    Foctee  
       2019-06-23 13:53:37 +08:00
    楼主贴出的 php 代码有两个语法错误
    $content=’ this is a test message'; 楼主想要的应该是=> $content= 'this is a test message';
    $paras['sendInfo'] ][0]=$sendInfo; 楼主想要的应该是=> $paras['sendInfo'][0]=$sendInfo;
    然后我把修改后的代码运行了之后,json 输出的是=>
    {"content":"this is a test message","funCode":"1002","applicationId
    ":"HsqjSYsn6QjTrqzdW","password":"6VnLZlVwKf","sendInfo":[{"sendId":"0","mobile"
    :"18899990000"}]}"
    imdong
        13
    imdong  
       2019-06-23 14:15:00 +08:00
    根据 json 规范(如果我没记错的话),json 中的 key 和 字符串 value 必须用双引号。

    而 php 生成的 json 是符合这个规范的(相关我已知的所有规范)

    而楼主提供的 py 代码中,json 是 单引号。
    是创建一个对象,然后生成 json 么?

    假设如此,在 php 中如果,是数组 不能用
    $paras['sendInfo'] ][0]=$sendInfo

    要改成

    ```
    $paras = array(
    'content' => $content,
    'funCode' => $funcode,
    'applicationId' => $ApplicationID,
    'password' => $Password,
    'sendInfo' => []
    );

    $sendInfo = array(
    'sendId ' => '0',
    'mobile ' => '18899990000'//手机号码
    );
    $paras['sendInfo'][] = $sendInfo;
    ```

    不然 $paras['sendInfo'] 会是一个对象

    对象的 key 是 0
    Dogergo
        14
    Dogergo  
       2019-06-24 09:47:33 +08:00
    你需要看接口需要的是一个 JSON 字符串还是一个 JSON 对象,php json_encode 是默认字符串的话,如果需要转成 json 对象需要传递额外参数 JSON_FORCE_OBJECT
    LeeLou
        15
    LeeLou  
    OP
       2019-06-24 09:50:58 +08:00
    @imdong 'sendInfo' => []是直接报错的,不行。$paras['sendInfo'][]和$paras['sendInfo'][0]的效果可能一样。改了这个还是不行。 我的 php 版本比较低 5.1.6
    @Foctee 不好意思,之前发帖子的时候,没有注意,那两个其实是对的。
    @garlics,不是特别清楚,funMain 方法要的是什么,但是从 python 来看,应该是 json 字符串吧
    imdong
        16
    imdong  
       2019-06-24 09:59:44 +08:00
    !!!!!!! 5.1.6 ???你没打错吧,不是 7.1 ?

    不好意思,版本太老没用过,劝退了。
    garlics
        17
    garlics  
       2019-06-24 14:53:47 +08:00
    @LeeLou 这个不一定,或许你可以试下$result=$client->funMain($paras);
    你可以看下他这个函数是怎么实现的啊
    encro
        18
    encro  
       2019-06-24 15:14:34 +08:00
    为什么不怀疑是 wsdl 的问题,PHP 的 wsdl 是有一点不标准的,有比较 encode 的结果吗?

    另外,json_encode 有参数,建议看看 https://www.php.net/manual/en/function.json-encode.php
    LeeLou
        19
    LeeLou  
    OP
       2019-06-25 08:10:37 +08:00
    @encro,肉眼看不出 encode 的结果,就算直接把 python 的结果直接从 php 发出去也失败
    encro
        20
    encro  
       2019-06-25 09:06:02 +08:00
    肉眼看不出 encode 的结果?
    是看不出区别还是没有弄出来?
    @LeeLou
    LeeLou
        21
    LeeLou  
    OP
       2019-06-25 10:48:43 +08:00
    @encro 肉眼看不出区别的。 而且也把 python 生成的 encode 结果复制到 php 里作为字符串了,也是不能正常工作
    cquptzzq
        22
    cquptzzq  
       2019-06-25 21:02:06 +08:00
    找个网站把生成的 json 弄进去检查下格式就出来了。http://www.bejson.com/
    php 的 json_encode()几乎不可能出错,官方的常用函数都出错,可就笑死人了。
    c++和 java 倒是容易转 json 出错,最常见的就是有数字的情况,json 要求 key 是字符串,很多 java 和 c++都是拿的网上流传的方法转的 json,那些方法细节可能有问题。
    我就见过 java 生成出这样的 json:
    {1: "a"}
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1096 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 19:52 · PVG 03:52 · LAX 11:52 · JFK 14:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.