最近要用到通过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的应用就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。