PHP curl 关于 put 和 post 使用上的一个小问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
pinews
V2EX    程序员

PHP curl 关于 put 和 post 使用上的一个小问题

  •  
  •   pinews 2019-11-24 04:50:02 +08:00 3377 次点击
    这是一个创建于 2228 天前的主题,其中的信息可能已经有所发展或是发生改变。
    ucloud 对象存储在上传单文件,api 和 sdk 给我造成了一点困扰,api 说了 HTTP 方法是 put,但 phpsdk 用的 postfields,这不是 post 吗?参考网页和腾讯的 sdk 都是乖乖用的 UPLOAD READATA。
    对于我来说奇怪的地方在于,ucloud 用的 file_get_contents,而后面用的 fopen,如果把 fopen 改成 file_get_contents (相当于 fopen,fread,fclose 的集合)就会报错,说必须用 file_handle。
    腾讯的也可以按照 ucloud 的做法用,网易会报错认证失败。

    之所以这样是因为,put 和 post 最大区别在于 post 可以提交多个字段的内容,多个字段内容用&或者随机字符边界分割。
    如果提交的只有一个内容,格式应该是没区别的,所以在对象存储上传单文件的时候用 postfields,服务器收到的内容是一样的,之所以 ucloud 和腾讯可以通过,应该是忽略了收到方法为 post,而是直接固定用了 put,而网易按收到的方法校验,file_get_contents 显然比 fopen 这个方法好用啊,fopen 还要接着写个 fclose,或许 ucloud 在这里偷了个懒。
    curl 并不是靠传来的方法作为使用方法,而是用实际判断真实方法,用 upload 就一定是 put,用 postfields 就会是 post。

    我奇怪的就是为什么 READATA 一定要是个资源句柄,而不是文件的真实内容呢?

    c#用的也是 openread 方法,c#不太懂,我看了 curl 的源码也看不懂,不知道 READATA 和 postfields 最后在哪产生了分别。
    14 条回复    2019-12-16 08:59:44 +08:00
    eason1874
        1
    eason1874  
       2019-11-24 05:58:28 +08:00   1
    你用的什么 sdk ?我刚看了 ucloud 对象存储文档,他们放在 Github 的 PHP SDK 上传文件方法是 put,表单上传才是 post。

    至于用 fopen 还是 file_get_contents,服务器那边分不出来,你改了报错说明你 file_get_contents 没用对。

    各家厂商签名方法大多不一样,你拿这家 SDK 代码去请求另一家的接口,能用是巧合,报错才是常态。
    lolizeppelin
        2
    lolizeppelin  
       2019-11-24 08:55:39 +08:00 via Android
    put 和 post 最大区别在于 post 可以提交多个字段的内容,多个字段内容用&或者随机字符边界分割。


    没有这个区别
    duola
        3
    duola  
       2019-11-24 09:32:22 +08:00
    我的理解也是跟二楼的差不多。
    loginv2
        4
    loginv2  
       2019-11-24 10:17:46 +08:00
    ucloud 的这个 SDK php 版本有问题,根本无法成功,估计也没人用,所以没人反馈
    jinliming2
        5
    jinliming2  
       2019-11-24 13:17:57 +08:00 via iPhone
    POST 和 PUT 本质上除了 method 不一样以外,没有任何区别
    EminemW
        6
    EminemW  
       2019-11-24 14:12:58 +08:00
    PUT 和 POST 最大的区别难道不是:PUT 幂等,POST 不幂等
    pinews
        7
    pinews  
    OP
       2019-11-24 18:33:01 +08:00
    @EminemW 这里指实际应用,不是理念。
    @lolizeppelin
    @duola
    @jinliming2 form 表单都不支持 put,论本质是 hack。
    pinews
        8
    pinews  
    OP
       2019-11-24 18:34:41 +08:00
    @pinews 在 curl 这里是被强制区分的。
    xiaotuzi
        9
    xiaotuzi  
       2019-11-25 08:23:11 +08:00 via iPhone
    看了题主的内容,我同意 2 楼的。
    get 和 post 都是指定的传输方式,就算 form 也得指定提交方式,默认是 get。
    另外,如果 url 上携带了&拼接的参数,又使用 post 提交几个其他的参数,最后还是认为 post 提交。
    get,post 都有提交多个参数,curl 直接把 post 提交的数组拼接成&的形式,然后再提交。
    lolizeppelin
        10
    lolizeppelin  
       2019-11-25 11:42:27 +08:00
    没有区别, 有区别的是服务端根据 rfc 标准如何处理,以及客户端(库)是如何处理的

    a=1&b=2 可以在 url 后面,也可以在 body 里.
    到底是在 url 里还是在 body 需要看客户端代码如何处理的
    如果在 url 里还会受到服务器端包头长度限制的影响
    lolizeppelin
        11
    lolizeppelin  
       2019-11-25 11:45:06 +08:00
    @pinews

    a=1&b=2 不一定要看作 form 表单, 服务器端也可以认为是 filter

    按现在的流行 a=1&b=2 作为 filter,具体数据在 body 里以 json 存放
    pinews
        12
    pinews  
    OP
       2019-11-26 00:26:56 +08:00
    也许是楼上几位朋友没用 ucloud 的 phpsdk,而且对 curl 也不太了解,所以回避了我原文的问题,而是抓住我不太严谨的话语无限展开了。
    第一,我说过了,如果你提交的是一个内容,或者你把多个内容当成一个内容去发送,在技术上当然可以没有区别。我认为这是一种退步,因为已经给你提供多个内容的方法,你弃之不用,自己造轮子。

    第二,post,对于文件类型,用&分割内容不合适了,而是用的随机字符做边界,哪怕你只有一个文件内容。而 put 本身是针对一个内容的,当然没有&也不会有随机字符边界,这时候按标准是不一样的。

    第三 curl 在上传文件时,post 和 put 不仅对文件的要求不一样(一个是文件内容,一个是文件句柄),接受方法也不一样(一个是 postfield,一个是 READATA )

    第四,ucloud 虽然能用,但是错的,之所以能用就是从客户端技术上没区别的,而服务器端也没有验证。

    第五,我的错误在于没有认识到有价值的回答藏于深海,浮躁的回答飘荡于风中。
    pinews
        13
    pinews  
    OP
       2019-11-26 00:34:32 +08:00
    我猜测一个原因在于不做分割的情况下,post 只适合小文件传输,所以直接读取了文件全部内容,而 put 可以做大文件传输,不适合读取全部内容到内存中,而是提供了一个文件句柄,可以在传输过中一边读取,一边传输一边读取。
    大概是这样吧。。。。。
    encro
        14
    encro  
       2019-12-16 08:59:44 +08:00
    好像 POST 和 PUT 唯一区别在头:
    PUT URL, POST URL

    一般 Post 用于新增,PUT 用于修改
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2968 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 33ms UTC 13:33 PVG 21:33 LAX 05:33 JFK 08:33
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86