最近要用到通过post上传文件,网上盛传的有curl的post提交和fsockopen,其中curl最简单,于是从最简单的说起。
这是简单的将一个变量post到另外一个页面
1
2
3
4
5
6
7
8
9
|
$url = '' ; $data = array ( 'a' => 'b' ); $ch = curl_init(); curl_setopt( $ch , CURLOPT_URL, $url ); curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1); curl_setopt( $ch , CURLOPT_POST, true); curl_setopt( $ch , CURLOPT_POSTFIELDS, $data ); $ret = curl_exec( $ch ); curl_close( $ch ); |
主要说下这个选项CURLOPT_RETURNTRANSFER:如果设置为true/1,则curl_exec的时候不会自动将请求网页的内容输出到屏幕,$ret为请求网页的内容,如果设置为false/0,则curl_exec的时候会自动将请求网页的内容输出到屏幕,此时如果请求成功的话$ret的内容是1或者true。
下面是上传本地文件的代码,如果需要上传远程文件,则先down到本地,然后删掉即可(如有同学有别的办法还请告知):
1
2
3
4
5
6
7
8
9
10
|
$url = '' ; $file = '1.jpg' ; $field [ 'uploadFile' ] = '@' . $file ;(uploadFile为接收端的name名) $ch = curl_init(); curl_setopt( $ch , CURLOPT_URL, $url ); curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1); curl_setopt( $ch , CURLOPT_POST, 1); curl_setopt( $ch , CURLOPT_POSTFIELDS, $field ); $ret = curl_exec( $ch ); curl_close( $ch ); |
这是fsockopen的办法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
$uploadInfo = array ( 'host' => '' , 'port' => '80' , 'url' => '/upload.php' ); $fp = fsockopen ( $uploadInfo [ 'host' ], $uploadInfo [ 'port' ], $errno , $errstr ); $file = '1.jpg' ; $content = file_get_contents ( $file ); $boundary = md5(time()); $out .= "--" . $boundary . "\r\n" ; $out .= "Content-Disposition: form-data; name=\"uploadFile\"; filename=\"" . $file . "\"\r\n" ; $out .= "Content-Type: image/jpg\r\n\r\n" ; $out .= $content . "\r\n" ; $out .= "--" . $boundary . "\r\n" ; fwrite( $fp , "POST " . $uploadInfo [ 'url' ]. " HTTP/1.1\r\n" ); fwrite( $fp , "Host:" . $uploadInfo [ 'host' ]. "\r\n" ); fwrite( $fp , "Content-Type: multipart/form-data; boundary=" . $boundary . "\r\n" ); fwrite( $fp , "Content-length:" . strlen ( $out ). "\r\n\r\n" ); fwrite( $fp , $out ); while (! feof ( $fp )){ $ret .= fgets ( $fp , 1024); } fclose( $fp ); $ret = trim( strstr ( $ret , "\r\n\r\n" )); preg_match( '/http:.*/' , $ret , $match ); return $match [0]; |
一、如何禁用fsockopen()
下面是两种常用的禁用fsockopen的方法。
1、修改php.ini,将 disable_functions = 后加入 fsockopen
2、修改php.ini,将 allow_url_fopen = On 改为 allow_url_fopen = Off
二、如何解决fsockopen函数被禁用
1、如果服务器没有同时禁用pfsockopen,那么直接将fsockopen函数替换为pfsockopen。
具体操作:搜索程序中的字符串 fsockopen( 替换为 pfsockopen(。示例如下
修改前:
1
|
$fp = fsockopen ( $host , 80, $errno , $errstr , 30); |
修改后:
1
|
$fp = pfsockopen( $host , 80, $errno , $errstr , 30); |
2、如果服务器同时禁用了pfsockopen,那么用其他函数代替,如stream_socket_client()。注意:stream_socket_client()和fsockopen()的参数不同。
具体操作:搜索程序中的字符串 fsockopen( 替换为 stream_socket_client(,然后,将原fsockopen函数中的端口参数“80”删掉,并加到$host。示例如下
修改前:
1
|
$fp = fsockopen ( $host , 80, $errno , $errstr , 30); |
修改后
1
|
$fp = stream_socket_client( $host . "80" , $errno , $errstr , 30); |
3、如果PHP版本低于5.0,fsockopen被禁用,又没有stream_socket_client()怎么办呢?自己写一个函数实现fsockopen的功能,参考代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function b_fsockopen( $host , $port , & $errno , & $errstr , $timeout ) { $ip = gethostbyname ( $host ); $s = socket_create(AF_INET, SOCK_STREAM, 0); if (socket_set_nonblock( $s )) { $r = @socket_connect( $s , $ip , $port ); if ( $r || socket_last_error() == EINPROGRESS) { $errno = EINPROGRESS; return $s ; } } $errno = socket_last_error( $s ); $errstr = socket_strerror( $errno ); socket_close( $s ); return false; } |
具体操作:
1.首先找到使用fsockopen函数的代码段,将上面代码加至其上端,搜索该代码段中的字符串fsockopen( 替换为 b_fsockopen(。
2.因为fsockopen函数返回文件指针所以可以被文件函数操作,但是这个b_fsockopen函数没能返回文件指针,需要继续修改代码段:用socket_read(替换掉 fread(,用socket_write(替换掉fwrite(,用socket_close(替换掉fclose(。
以上这篇浅谈php中curl、fsockopen的应用就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。