V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
adrianzhang
V2EX  ›  问与答

怎么观察 PHP 程序的执行

  •  1
     
  •   adrianzhang · 2015-08-30 18:43:42 +08:00 · 2500 次点击
    这是一个创建于 3380 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一个 PHP file ,向一个 web api 提出 POST 请求。我不懂 PHP ,想看看这个 POST 请求的整个 URL 是什么样的,怎么才能办到呢?
    这个 PHP file 现在我的电脑上,取名 test.php ,可以用 php test.php 运行。
    第 1 条附言  ·  2015-08-30 19:16:33 +08:00
    28 条回复    2015-08-30 22:53:25 +08:00
    chairuosen
        1
    chairuosen  
       2015-08-30 18:49:14 +08:00
    echo 大法好
    麻烦点的就是 ide+xdebug
    adrianzhang
        2
    adrianzhang  
    OP
       2015-08-30 18:53:29 +08:00
    @chairuosen 还是不太明白,用 echo 怎么看?
    falcon05
        3
    falcon05  
       2015-08-30 18:59:34 +08:00 via iPhone
    抓包,简单粗暴
    seki
        4
    seki  
       2015-08-30 19:00:04 +08:00   ❤️ 1
    echo 就相当于一些语言的 print
    想看哪个对象就 echo 哪个对象……
    adrianzhang
        5
    adrianzhang  
    OP
       2015-08-30 19:03:01 +08:00
    @falcon05 痛苦的是这是个 https 请求,我用了 tcpdump ,也是一片茫然~~

    @seki 懂了,多谢。
    adrianzhang
        6
    adrianzhang  
    OP
       2015-08-30 19:11:19 +08:00
    @seki 还是不出结果
    我是把源文件里: curl_setopt ($ch, CURLOPT_URL, $authUrl );
    改成
    $test = curl_setopt ($ch, CURLOPT_URL, $authUrl );
    echo $test;

    然后再执行 php test.php ,但是还是没有结果。应该改成什么呢?
    des
        7
    des  
       2015-08-30 19:31:31 +08:00   ❤️ 1
    @adrianzhang
    print_r ($ch );
    或者
    var_dump ($ch );
    $tset 只是个布尔值而已
    adrianzhang
        8
    adrianzhang  
    OP
       2015-08-30 19:33:01 +08:00
    @des 好的,我试试。
    shiny
        9
    shiny  
       2015-08-30 19:34:29 +08:00
    本地开 fiddler 然后设置 curl 的代理为 fiddler 的
    adrianzhang
        10
    adrianzhang  
    OP
       2015-08-30 19:43:32 +08:00
    @des 还是不行,麻烦看一眼那源代码,给个指示,该怎么截胡。。求你了。

    @shiny 啊呀,动静好大。。怎么在这个 php 里给 curl 设置代理呢?
    feiyuanqiu
        11
    feiyuanqiu  
       2015-08-30 19:52:28 +08:00   ❤️ 1
    //Create an Http Query.//
    $paramArr = http_build_query ($paramArr );
    //Set the Curl URL.
    curl_setopt ($ch, CURLOPT_URL, $authUrl );
    //Set HTTP POST Request.
    curl_setopt ($ch, CURLOPT_POST, TRUE );
    //Set data to POST in HTTP "POST" Operation.
    curl_setopt ($ch, CURLOPT_POSTFIELDS, $paramArr );

    $authUrl 是请求 url 地址
    $paramArr 是 post 过去的参数

    你可以直接在 curl_setopt ($ch, CURLOPT_POSTFIELDS, $paramArr ); 这里 var_dump ($authUrl, $paramArr );exit; 就能看到你要的东西了
    ljbha007
        12
    ljbha007  
       2015-08-30 19:59:57 +08:00   ❤️ 1
    代码里有啊

    http://api.microsofttranslator.com/v2/Http.svc/Detect?text=

    text 是参数
    请求头里有 basic auth


    OAuth 的地址是

    https://datamarket.accesscontrol.windows.net/v2/OAuth2-13

    参数文章里有说
    ljbha007
        13
    ljbha007  
       2015-08-30 20:04:42 +08:00
    先访问 https://datamarket.accesscontrol.windows.net/v2/OAuth2-13

    然后照这个格式 post

    grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com

    {0}是 client_id
    {1}是 client_secret

    返回的是个 json
    access_token 字段就是 access_token

    http://api.microsofttranslator.com/v2/Http.svc/Detect?text=
    然后请求翻译 api 的时候加个 Authorization: Bearer {access_token}的请求头就可以了
    {access_token}是前面得到的请求头
    ChoateYao
        14
    ChoateYao  
       2015-08-30 20:21:59 +08:00   ❤️ 1
    CURLOPT_VERBOSE 、 CURLOPT_STDERR
    启用这两个参数即可。
    adrianzhang
        15
    adrianzhang  
    OP
       2015-08-30 20:27:54 +08:00
    @feiyuanqiu
    多谢!明白了这个构造。

    @ljbha007
    很感激这么详细的说明。我是用 python 来构造这个的。所以就想知道 PHP 这个实现跟我的到底哪儿不一样。不知你是否也懂 python ,若懂,也请看看我这段代码到底怎么回事,总是拿不回 token 的 json 值。写成以下这样,总是得到 400 bad request 。



    class Microsoft_translator_api ():
    """translate text only"""

    def __init__(self, text ):
    self.text = text
    self.request_url = "datamarket.accesscontrol.windows.net/v2/OAuth2-13"
    self.client_id = "我的应用名"
    self.client_secret = "我的密钥"
    self.grant_type = "client_credentials"
    self.scope = "http://api.microsofttranslator.com"

    def get_token (self ):
    params = urllib.urlencode ({'@grant_type': self.grant_type, '@scope': self.scope, '@client_id': self.client_id, '@client_secret': self.client_secret})
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    request_token = httplib.HTTPConnection (self.request_url )
    request_token.request ("POST", "", params, headers )
    response = request_token.getresponse ()
    print response.status, response.reason
    token = response.read ()
    #print token
    request_token.close ()
    return (token )
    adrianzhang
        16
    adrianzhang  
    OP
       2015-08-30 20:28:31 +08:00
    @ChoateYao 谢谢,又学了一招。
    MaiCong
        17
    MaiCong  
       2015-08-30 20:31:20 +08:00
    adrianzhang
        18
    adrianzhang  
    OP
       2015-08-30 20:32:45 +08:00
    @ljbha007 忘记用 markdown 了。代码如下:

    ```

    class Microsoft_translator_api ():
    """translate text only"""

    def __init__(self, text ):
    self.text = text
    self.request_url = "datamarket.accesscontrol.windows.net/v2/OAuth2-13"
    self.client_id = "我的应用名"
    self.client_secret = "我的密钥"
    self.grant_type = "client_credentials"
    self.scope = "http://api.microsofttranslator.com"

    def get_token (self ):
    params = urllib.urlencode ({'@grant_type': self.grant_type, '@scope': self.scope, '@client_id': self.client_id, '@client_secret': self.client_secret})
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    request_token = httplib.HTTPConnection (self.request_url )
    request_token.request ("POST", "", params, headers )
    response = request_token.getresponse ()
    print response.status, response.reason
    token = response.read ()
    #print token
    request_token.close ()
    return (token )

    ```
    ljbha007
        19
    ljbha007  
       2015-08-30 20:32:57 +08:00   ❤️ 1
    @adrianzhang
    你参数对象为什么要加 @符号?
    还有 Accept 改成 application/json 活着直接删掉试试
    adrianzhang
        20
    adrianzhang  
    OP
       2015-08-30 20:33:41 +08:00
    为什么不支持我的代码块??
    mudone
        21
    mudone  
       2015-08-30 20:35:26 +08:00   ❤️ 1
    curl_setopt ($ch, CURLOPT_VERBOSE, true );
    adrianzhang
        22
    adrianzhang  
    OP
       2015-08-30 20:43:00 +08:00
    @ljbha007
    加 @是参考这里: https://docs.python.org/2/library/httplib.html 的 POST sample 。
    经测试,去掉 @,还是 400 ;去掉 text/plain ,还是 400 ; 改成 application/json ,还是 400 。太邪门了。
    ljbha007
        23
    ljbha007  
       2015-08-30 20:46:26 +08:00   ❤️ 1
    你用 chrome 装个叫 postman 的工具测一下试试 不需要写代码
    先把参数调对了再说
    adrianzhang
        24
    adrianzhang  
    OP
       2015-08-30 20:48:02 +08:00
    @ljbha007 好的,我试试。多谢。
    ljbha007
        25
    ljbha007  
       2015-08-30 22:12:39 +08:00   ❤️ 1
    @adrianzhang 试了一下就是 @符号的问题

    那个 sample 是坑人的 我就记得以前我没用过 @
    adrianzhang
        26
    adrianzhang  
    OP
       2015-08-30 22:36:30 +08:00
    @ljbha007
    目前发现的问题有:使用元组替换字典。这样才有正确的顺序。
    params = urllib.urlencode ((('grant_type', self.grant_type ), ('scope', self.scope ), ('client_id', self.client_id ), ('client_secret', self.client_secret )))

    请求是 https 而不是 http ,所以还要把 request_token = httplib.HTTPConnection (self.request_url )换成 request_token = httplib.HTTPSConnection (self.request_url )

    但现在这两个改了以后还是拿不到 json 格式的 token 。
    ljbha007
        27
    ljbha007  
       2015-08-30 22:38:27 +08:00   ❤️ 1
    @adrianzhang 你先不写代码 手动把参数调对吧
    adrianzhang
        28
    adrianzhang  
    OP
       2015-08-30 22:53:25 +08:00
    @ljbha007
    又解决一个: request_url 只能设置域名,不可设置路径,要在 request_token.request ("POST", "", params, headers ) 这句里面 POST 后那个地方加上路径。
    但仍然不行。

    最后!还是太谢谢你了!! 最后最后一个问题就是:要去掉那个"Accept": "text/plain"
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1019 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 19:41 · PVG 03:41 · LAX 11:41 · JFK 14:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.