1. 用 file_get_contents 以 get 方式获取内容:
3 | $html = file_get_contents ( $url ); |
2. 用fopen打开url,以get方式获取内容
03 | $fp = fopen ( $url , 'r' ); |
04 | stream_get_meta_data( $fp ); |
08 | $result .= fgets ( $fp , 1024); |
10 | echo "url body: $result" ; |
3. 用file_get_contents函数,以post方式获取url
这种方法我们之前点了一下,具体可以参考 stream_context_create()模拟POST/GET 这篇文章。
04 | 'site' => 'www.nowamagic.net' , |
05 | 'name' => 'nowa magic' ); |
07 | $data = http_build_query( $data ); |
13 | 'header' => 'Content-type:application/x-www-form-urlencoded' , |
20 | $context = stream_context_create( $options ); |
21 | $result = file_get_contents ( $url , false, $context ); |
4. 用 fsockopen 函数打开url,以get方式获取完整的数据,包括header和body
这种方法在小节前面谈得很多了,这里不厌其烦地再列举一下:
03 | function get_url( $url , $cookie =false) |
05 | $url = parse_url ( $url ); |
06 | $query = $url [ 'path' ]. "?" . $url [ 'query' ]; |
08 | $fp = fsockopen ( $url [ 'host' ], $url [ 'port' ]? $url [ 'port' ]:80 , $errno , $errstr , 30); |
14 | $request = "GET $query HTTP/1.1\r\n" ; |
15 | $request .= "Host: $url[host]\r\n" ; |
16 | $request .= "Connection: Close\r\n" ; |
17 | if ( $cookie ) $request .= "Cookie: $cookie\n" ; |
23 | $result .= @ fgets ( $fp , 1024); |
30 | function GetUrlHTML( $url , $cookie =false) |
32 | $rowdata = get_url( $url , $cookie ); |
35 | $body = stristr ( $rowdata , "\r\n\r\n" ); |
36 | $body = substr ( $body ,4, strlen ( $body )); |
45 | echo GetUrlHTML( $url ); |
程序输出:
01 | Query:/php/sock.php?site=nowamagic.netHTTP/1.1 200 OK |
02 | Date : Wed, 19 Feb 2014 06:06:25 GMT |
03 | Server: Apache/2.2.3 (CentOS) |
04 | X-Powered-By: PHP/5.3.3 |
08 | Content-Type: text/html; charset=UTF-8 |
12 | Query:/php/sock.php?site=nowamagic.net Welcome to NowaMagic |
5. 用fsockopen函数打开url,以POST方式获取完整的数据,包括header和body
03 | function HTTP_Post( $URL , $data , $cookie , $referer = "" ) |
07 | $URL_Info = parse_url ( $URL ); |
11 | $referer = "www.nowamagic.net" ; |
14 | foreach ( $data as $key => $value ) |
15 | $values []= "$key=" .urlencode( $value ); |
16 | $data_string =implode( "&" , $values ); |
19 | if (!isset( $URL_Info [ "port" ])) |
24 | $request .= "POST " . $URL_Info [ "path" ]. " HTTP/1.1\n" ; |
25 | $request .= "Host: " . $URL_Info [ "host" ]. "\n" ; |
26 | $request .= "Referer: $referer\n" ; |
27 | $request .= "Content-type: application/x-www-form-urlencoded\n" ; |
28 | $request .= "Content-length: " . strlen ( $data_string ). "\n" ; |
29 | $request .= "Connection: close\n" ; |
31 | $request .= "Cookie: $cookie\n" ; |
34 | $request .= $data_string . "\n" ; |
36 | $fp = fsockopen ( $URL_Info [ "host" ], $URL_Info [ "port" ]); |
41 | $result .= fgets ( $fp , 1024); |
51 | 'site' => 'www.nowamagic.net' , |
52 | 'name' => 'nowa magic' ); |
57 | echo HTTP_Post( $url , $data , $cookie , $referer ); |
程序输出:
02 | Date : Wed, 19 Feb 2014 06:15:38 GMT |
03 | Server: Apache/2.2.3 (CentOS) |
04 | X-Powered-By: PHP/5.3.3 |
08 | Content-Type: text/html; charset=UTF-8 |
6. 使用curl库,使用curl库之前,可能需要查看一下php.ini是否已经打开了curl扩展。
使用 curl 代码比较简洁,代码也比较规范,容易理解:
05 | curl_setopt ( $ch , CURLOPT_URL, $url ); |
06 | curl_setopt ( $ch , CURLOPT_RETURNTRANSFER, 1); |
07 | curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT, $timeout ); |
08 | $file_contents = curl_exec( $ch ); |
fsockopen 是比较底层的调用,属于网络系统的socket调用,而curl经过的包装支持HTTPS认证,HTTP POST方法, HTTP PUT方法, FTP上传, kerberos认证,HTTP上传, 代理服务器, cookies, 用户名/密码认证, 下载文件断点续传,上载文件断点续传,http代理服务器管道( proxy tunneling), 甚至它还支持IPv6, socks5代理服务器,,通过http代理服务器上传文件到FTP服务器等等,功能十分强大。fsockopen 返回的是没有处理过的数据,包括数据的长度数据内容和数据的结束符。而curl是处理后的内容。
在用户使用时,curl 更加方便,但其参数很多,配置稍微复杂,fsockopen 则有固定的几个参数,简单,但获取结果可能需要再做处理。
那么file_get_contents呢?
有些时候用 file_get_contents() 调用外部文件容易超时报错。curl 效率比 file_get_contents() 和 fsockopen() 高一些,原因是CURL会自动对DNS信息进行缓存。
file_get_contents / curl / fsockopen 在当前所请求环境下选择性操作,没有一概而论。
file_get_contents 需要php.ini里开启allow_url_fopen,请求http时,使用的是http_fopen_wrapper,不会keeplive的话curl是可以的。 file_get_contents()单个执行效率高,返回没有头的信息。
这个是读取一般文件的时候并没有什么问题,但是在读取远程问题的时候有可能就会出现问题。 如果是要打一个持续连接,多次请求多个页面。那么file_get_contents和fopen就会出问题。 取得的内容也可能会不对。所以做一些类似采集工作的时候,肯定就有问题了。
fsockopen 较底层,可以设置基于UDP或是TCP协议去交互,配置麻烦,不易操作。 返回完整信息。
总之,file_get_contents 和 curl 能干的,socket都能干。socket能干的,curl 就不一定能干了 。file_get_contents 更多的时候只是去拉取数据。效率比较高也比较简单。
只讨论 curl 与file_get_contents 的话,有这么一些结论:
- fopen /file_get_contents 每次请求都会重新做DNS查询,并不对DNS信息进行缓存。但是CURL会自动对DNS信息进行缓存。对同一域名下的网页或者图片的请求只需要一次DNS查询。这大大减少了DNS查询的次数。所以CURL的性能比fopen /file_get_contents 好很多。
- fopen /file_get_contents在请求HTTP时,使用的是http_fopen_wrapper,不会keeplive。而curl却可以。这样在多次请求多个链接时,curl效率会好一些。
- fopen / file_get_contents函数会受到php.ini文件中allow_url_open选项配置的影响。如果该配置关闭了,则该函数也就失效了。而curl不受该配置的影响。
- curl可以模拟多种请求,例如:POST数据,表单提交等,用户可以按照自己的需求来定制请求。而fopen / file_get_contents只能使用get方式获取数据。
PS:file_get_contents()函数获取https链接内容的时候,需要php 中mod_ssl的支持(或安装opensll)。
结论就是,curl 效率及稳定都比 file_get_contents() 要好,fsockopen 也很强大,但是比较偏底层。
http://www.nowamagic.net/academy/detail/12220248