php三种post数据方法Curl、socket、file_get_contents 有什么区别三种方法都要加上 stream_set_blocking 才可以实现无须等待马上返回结果吗?一般什么情况下用哪种方法,有没有人总结过的,谢啦。。

解决方案 »

  1.   

    拖拉机,公交车,轿车 都是运输工具,他们的轮子在转动上有什么区别没有区别.curl 不需要加你说的那个什么东东...
      

  2.   

    curl无脑
    socket有脑
    file_get_content+stream_context_create半脑残
    stream_set_blocking是设置文件描述符非阻塞,可作用于regular files and socket streams,除非你用select+socket,否则对PHP这个语言编程没有益处,也许你期待的是stream_set_timeout。
      

  3.   

    file_get_contents、curl、socket 三者按顺序来说,一个比一个用起来复杂,灵活度更高。file_get_contents 只能用一个 url 来获取目标内容(其实是不能做 post 的),基本没什么参数可以控制。curl 用于在 HTTP/FTP 协议的层级上进行通信,相应地,支持协议规定的一些参数控制。socket 则是在 TCP 协议的层级上进行通信,当然也有相应的控制参数。如果仅是实现常规的 HTTP 功能,就不要直接用 socket 了。至于你提到的 stream_set_blocking,应该只在 socket 里面能用到。当 PHP 作为一种 web 页面脚本语言的时候,“无须等待马上返回”这个特性基本没什么用处。
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  4.   

    哈哈,好犀利的比喻。。
    我期待的不是stream_set_timeout,它应该是控制超时的吧,其实我更想知道这三种方法如何实现类似非阻塞的功能。。
      

  5.   

    回答的真详细,非常感谢。。
    我刚才试了stream_set_blocking貌似真的只能在socket里用到,这种是什么流?
    “当 PHP 作为一种 web 页面脚本语言的时候,“无须等待马上返回”这个特性基本没什么用处。”这句话不太明白,例如我想实现在PHP程序里,去执行A程序的时候,B程序无须等待A执行完而继续执行,这时候我用fsockopen+stream_set_blocking
      

  6.   

    一般进行网络通信的程序,都是要接收响应结果并继续处理的,如果是设置成非阻塞模式,那就是要进行异步处理,一般来说这意味着“多线程”。当 PHP 作为一种 web 页面脚本语言来使用的时候,基本上不具备多线程处理能力,所以基本上不会用到“无须等待马上返回”这种处理方式。(需要澄清的是,在 web 容器里,响应每个 HTTP 请求的 PHP 程序都是在一个独立的线程里工作的,这是 web 容器的多线程能力,不是 PHP 程序的多线程能力)当然也有例外的应用场景,随便说几个:1. PHP 不是作为 web 页面脚本语言来使用,而是用来实现一个独立应用程序(这种程序一般都通过 php.exe 来启动运行),比如聊天室的客户端。2. PHP 程序只需要向通信的对方发送数据,而完全不关心返回结果,甚至对发送是否成功都不关心。3. 用轮询的方式完成整个通信过程。
      

  7.   

    又学到东西了。。
    最后问一下,如果有那么两个例子:
    1、PHP发邮件,因为发邮件需要一些时间,我要的效果是无须得到返回结果,马上提示用户已发送成功。
    2、A和B通信,A会不定时向B发送数据通知对方,一开始我是打算做成你所说的第2点,不关心返回结果和是否成功的,否则A会受到B的影响?
    这样的例子,大侠你们一般怎么做的?
      

  8.   

    1、你所谓的三种方式都不可能出现“无须等待马上返回"
    因为他们都只在执行完毕后才会返回2、对于你#8的1,由于对方没有返回,所以你不能说“发送成功”。而只能说“已发送”。注意这是用本质的区别的3、对于你#8的2,由于php内置函数并不提供他说的功能。所以你若不采取一些非常规的手段的话,是做不到的
      

  9.   

    file_get_contents一般用来获取不需要登录的数据
      

  10.   

    fsockopen+fwrite可以实现,linux上还有其它方式
      

  11.   

    在网站里,这个需求可以这样实现:当用户提交一个表单,请求发送一封邮件时,服务端把该请求记录入数据库,并给浏览器返回一个提示“已发送”的页面(如 #11 楼所说,这时只能说“已发送”,而不能说“发送成功”),同时在该页面里用 <script> 标签向服务器发起另一个请求,服务端在处理这个请求的时候从数据库中取出记录并处理(这个是真正发送邮件的全过程,不怕耗时长,不用考虑异步处理)。至于“发送成功”,如果你希望用户能了解邮件发送的最终结果,可以提供另外的功能页面进行查询。你这里 B 是什么?socket 服务端还是 HTTP 服务端?其实无论哪种服务端,也无论你使用的是 curl 还是 fsockopen,都不用考虑“非阻塞模式”,就可以达到你要求的效果。(以下描述可能不是“完全”准确,仅是讨论一个梗概)非阻塞模式,只是在进行“可能被阻塞”的操作时才有意义,在网络通信中,open/read/write/close 这几个操作,open / read 是很可能被阻塞的,因为要等待对方的响应,而 write / close 可以认为是无阻塞的。而 open 又可以假设对方会很快反应,所以矛盾主要集中在 read 上。所以,在你描述的场景中,你只要不去做 read 就好了(对于 curl 而言,就是设置一个很小的 timeout 也就差不多了)。