中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

php模擬post請(qǐng)求發(fā)送文件代碼

2018-07-20    來(lái)源:open-open

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬(wàn)Linux鏡像隨意使用

由于項(xiàng)目需要,需要本地服務(wù)器接收數(shù)據(jù)后,再將數(shù)據(jù)轉(zhuǎn)發(fā)到另外一臺(tái)服務(wù)器上,故要用到模擬post請(qǐng)求發(fā)送數(shù)據(jù),當(dāng)然數(shù)據(jù)中也包含文件流。

curl是php比較常用的方式之一,一般代碼如下:

    $params1 = "test";  
    $params2 = "@".$absolute_path;//如果是文件 則參數(shù)為"@"+絕對(duì)路徑  
    $post_data = array(    
        'params1' => $params1,    
        'params2' => $params2,  
    );  
    function postData($url, $data){        
        $ch = curl_init();        
        $timeout = 300;         
        curl_setopt($ch, CURLOPT_URL, $url);   //請(qǐng)求地址  
        //curl_setopt($ch, CURLOPT_REFERER, $ip);//構(gòu)造來(lái)路      
        curl_setopt($ch, CURLOPT_POST, true);  //post請(qǐng)求  
        curl_setopt($ch, CURLOPT_BINARYTRANSFER,true);//二進(jìn)制流      
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);      //數(shù)據(jù)  
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  //當(dāng)CURLOPT_RETURNTRANSFER設(shè)置為1時(shí) $head 有請(qǐng)求的返回值      
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);    //設(shè)置請(qǐng)求超時(shí)時(shí)間    
        $handles = curl_exec($ch);        
        curl_close($ch);          
        return $handles;  
    }  

對(duì)方是java服務(wù)器,我只知道接口,并不知道對(duì)方如何處理文件接收的。上面這種方式在win7 wamp環(huán)境下是成功的,但是將代碼放到centOS+Nginx服務(wù)器上卻失敗,返回的消息是文件接收失敗。經(jīng)過(guò)抓包分析,發(fā)現(xiàn)在win7 wamp下發(fā)的包和centos nginx下發(fā)的http包格式有區(qū)別。一般情況下curl默認(rèn)把content_type設(shè)為了multipart/form-data,在我的機(jī)器上 win7 wamp下是如此,但是centos nginx下卻是application/x-www-form-urlencoded。當(dāng)然這也可能是服務(wù)器配置問(wèn)題,只是我并不知道問(wèn)題在哪。然后我 又查看了下PHP版本,同是PHP5.3.X,但是有細(xì)微差別。也不排除是PHP版本的問(wèn)題。之后添加代碼:
$header = array(  
    'Content-Type: multipart/form-data',  
);  
curl_setopt( $ch, CURLOPT_HTTPHEADER, $header); 

設(shè)置header,但是在centos下依舊無(wú)效。居然無(wú)法改變content-type,簡(jiǎn)直坑爹。

后來(lái)在技術(shù)總監(jiān)的幫助下,看了PHP官方網(wǎng)站上的一個(gè)鏈接http://php.net/manual/en /class.curlfile.php,參照官網(wǎng)做法在win wamp和centos nginx下post請(qǐng)求都成功了。仔細(xì)閱讀了代碼,發(fā)現(xiàn)做法竟是完整的書(shū)寫了http請(qǐng)求的body部分,而不用curl自己生成的部分,不得不佩服。 下面放出代碼:

    function postData($url, $data = array(), $data1 = array()){        
        $header = array(  
            'Content-Type: multipart/form-data',  
        );  
        $ch = curl_init();   
        curl_setopt ($ch, CURLOPT_URL, $url);  
        curl_setopt( $ch, CURLOPT_HTTPHEADER, $header);  
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);   
        curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT,10);  
        curl_setopt ($ch, CURLOPT_BINARYTRANSFER,true);   
        //curl_setopt ($ch, CURLOPT_POSTFIELDS, $data);  
        curl_custom_postfields($ch, $data, $data1);  
        $dxycontent = curl_exec($ch);  
        curl_close($ch);  
        return $dxycontent;  
    }  
      
    /** 
    * For safe multipart POST request for PHP5.3 ~ PHP 5.4. 
    *  
    * @param resource $ch cURL resource 
    * @param array $assoc "name => value" 
    * @param array $files "name => path" 
    * @return bool 
    */  
    function curl_custom_postfields($ch, array $assoc = array(), array $files = array()) {    
        // invalid characters for "name" and "filename"  
        static $disallow = array("\0", "\"", "\r", "\n");  
          
        // build normal parameters  
        foreach ($assoc as $k => $v) {  
            $k = str_replace($disallow, "_", $k);  
            $body[] = implode("\r\n", array(  
                "Content-Disposition: form-data; name=\"{$k}\"",  
                "",  
                filter_var($v),   
            ));  
        }  
          
        // build file parameters  
        foreach ($files as $k => $v) {  
            switch (true) {  
                case false === $v = realpath(filter_var($v)):  
                case !is_file($v):  
                case !is_readable($v):  
                    continue; // or return false, throw new InvalidArgumentException  
            }  
            $data = file_get_contents($v);  
            $v = call_user_func("end", explode(DIRECTORY_SEPARATOR, $v));  
            $k = str_replace($disallow, "_", $k);  
            $v = str_replace($disallow, "_", $v);  
            $body[] = implode("\r\n", array(  
                "Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$v}\"",  
                "Content-Type: application/octet-stream",  
                "",  
                $data,   
            ));  
        }  
          
        // generate safe boundary   
        do {  
            $boundary = "---------------------" . md5(mt_rand() . microtime());  
        } while (preg_grep("/{$boundary}/", $body));  
          
        // add boundary for each parameters  
        array_walk($body, function (&$part) use ($boundary) {  
            $part = "--{$boundary}\r\n{$part}";  
        });  
          
        // add final boundary  
        $body[] = "--{$boundary}--";  
        $body[] = "";  
          
        // set options  
        return @curl_setopt_array($ch, array(  
            CURLOPT_POST       => true,  
            CURLOPT_POSTFIELDS => implode("\r\n", $body),  
            CURLOPT_HTTPHEADER => array(  
                "Expect: 100-continue",  
                "Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type  
            ),  
        ));  
    }  

參數(shù)傳遞無(wú)影響,若是文件則在絕對(duì)路徑前+"@"。唯一的區(qū)別就是將文件數(shù)據(jù)和普通數(shù)據(jù)用不同的數(shù)組區(qū)分開(kāi)來(lái),在模擬http的body部分時(shí)對(duì)其進(jìn)行不同的處理。最終成功上傳文件。

標(biāo)簽: CentOS isp 本地服務(wù)器 代碼 服務(wù)器

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇: Andriod實(shí)現(xiàn)刮刮卡的效果

下一篇:php圖形圖像處理基礎(chǔ)