1. 程式人生 > >CURL的使用及上傳圖片

CURL的使用及上傳圖片

CURL

什麼是curl,我的理解是curl就是一個模擬資料傳輸的庫。
能讓你通過URL和不同的伺服器進行互動,支援許多種協議。如:http、https、ftp、gopher、telnet、dict、file和ldap協議。同時也支援HTTPS認證、HTTP POST、HTTP PUT、 FTP 上傳(這個也能通過PHP的FTP擴充套件完成)、HTTP 基於表單的上傳、代理、cookies和使用者名稱+密碼的認證。

  • 安裝
    要使用PHP的cURL支援你必須在編譯PHP時加上–with-curl[=DIR] 選項,DIR為包含lib和include的目錄路徑。在include目錄中必須有一個名為curl,包含了easy.h和curl.h的資料夾。lib資料夾裡應該有一個名為libcurl.a的檔案。對於PHP 4.3.0你可以配置–with-curlwrappers 使cURL使用URL流。
    注意: Win32使用者注意 要在Windows環境下使用這個模組,libeay32.dll和ssleay32.dll必須放到PATH環境變數包含的目錄下。 不用cURL網站上的libcurl.dll。

當然現在由於整合環境的出現,或許不能說是安裝,因為當你整合環境安裝完成的時候,它會以一個擴充套件的形式存在並且預設開啟。phpinfo()檢視:
這裡寫圖片描述
如果真的額沒有開啟的話,就到php.ini中手動開啟即可。

基礎命令

方面下面的例子解釋,先列出幾個常用的命令。

//建立了一個curl會話資源,成功返回一個控制代碼
$ch = curl_init(); 
//設定url
curl_setopt($ch, CURLOPT_URL, "baidu.com"); 
//設定是否將響應結果存入變數,1是存入,0是直接echo出
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1
); //設定為post請求,1:是 0:否 curl_setopt($ch, CURLOPT_POST,1); //請求預設超時時間 curl_setopt($ch, CURLOPT_TIMEOUT, 60); // 1 or true 返回的內容作為變數儲存,而不是直接輸出 false or 0相反 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //0 or false 為不檢查證書 測試時候可以設定 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //post資料的時候進行資料提交,此命令略坑。 //使用 curl 並且引數為資料時,向伺服器提交資料時,
//http頭會發送content_type: application/x-www-form-urlencoded。 //這個是正常的網頁<form>提交表單時,瀏覽器傳送的頭部。 //而 multipart/form-data 知道這是用於上傳檔案的表單。包括了 boundary 分界符,會多出很多位元組。 //在沒有需要上傳檔案的情況下,儘量對 post 提交的資料進行 http_build_query 處理,再發送 curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // 執行,然後將響應結果存入$output變數 $output = curl_exec($ch); //捕獲控制代碼執行錯誤資訊 $error = curl_error($ch); // 關閉這個curl會話資源 curl_close($ch);

當然命令遠不止這些,而且上面的curl_setopt可以用curl_setopt_array();代替,並將引數以陣列的形式傳入。像這樣:

$opts = array(
    CURLOPT_TIMEOUT => 60,
    CURLOPT_RETURNTRANSFER => 1,
    ...
);
curl_setopt_array($ch, $opts);

CURL-GET請求

用一個小例子來說明下get請求
.預設請求方式是GET,所以不需要顯式指定GET方式

<?php
// 建立一個新cURL資源
$ch = curl_init();
// 設定URL和相應的選項
curl_setopt($ch, CURLOPT_URL, "http://www.baidu.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);
// 抓取URL並把它傳遞給瀏覽器
curl_exec($ch);
// 關閉cURL資源,並且釋放系統資源
curl_close($ch);
?>

你可以自己執行看一下。

CURL-POST請求

以前,我第一次解除curl就是因為這個post請求,上個例子

<?php
    $data=array(
    "name" => "guwenjie",
    "age" => "18"
    );

    $ch = curl_init(); 

    curl_setopt($ch, CURLOPT_URL, "http://guwenjie.freephp.top/test.php"); 
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); 
    curl_setopt($ch, CURLOPT_POSTFIELDS , http_build_query($data));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

    $output = curl_exec($ch); 

    echo $output;

    curl_close($ch);      

test.php

<?php  
    $phpInput=file_get_contents('php://input');
    echo urldecode($phpInput);

最後輸出:name=guwenjie&age=18

GET,POST介面統一

上面分別給了get,post請求的小demo,不過我們在使用的時候可能會出現這個地方需要get請求,另一個地方需要post請求,如果將介面統一的話會更方便。下面是我整理的統一介面:

/**
 * CURL-GET,POST統一介面
 * @param $url url地址
 * @param $params 請求引數
 * @param string $method 請求方法
 * @param string $cookie cookie設定
 * @param bool $multi 是否檔案上傳
 * @return mixed 返回請求結果
 * @throws Exception 錯誤異常丟擲
 */
function get_Api_Data($url, $params, $method = 'GET', $cookie = '', $multi = false)
{

    $opts = array(
        CURLOPT_TIMEOUT => 60,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_COOKIE => $cookie
    );

    /* 根據請求型別設定特定引數 */
    switch (strtoupper($method)) {
        case 'GET':
            $opts[CURLOPT_URL] = $url . '&' . http_build_query($params);
            break;
        case 'POST':
            //判斷是否傳輸檔案
            $params = $multi ? $params : http_build_query($params);
            $opts[CURLOPT_URL] = $url;
            $opts[CURLOPT_POST] = 1;
            $opts[CURLOPT_POSTFIELDS] = $params;
            break;
        default:
            throw new Exception('不支援的請求方式!');
    }
    /* 初始化並執行curl請求 */
    $ch = curl_init();
    curl_setopt_array($ch, $opts);
    $data = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);
    if ($error) {
        throw new Exception('請求發生錯誤:' . $error);
    }
    return $data;
}

CURL上傳圖片

下列上傳圖片的場景如下:
這裡寫圖片描述
隨手畫了一下,大致是這個流程。

  • 應用層
    客戶端上傳就不細說了,這個例子是我簡單寫的一個,在YII2框架的基礎上。
 public function actionUploadimg()
    {
        if (Yii::$app->request->isPost) {
            $file = $_FILES['file'];
            $url = Yii::$app->params['uploadImgUrl'];//url地址,設定在params.php中,你可以直接寫URL地址
            // 建立一個 cURL 控制代碼
            $ch = curl_init($url);
            // 建立一個 CURLFile 物件
            $cfile = curl_file_create($file['tmp_name'],$file['type'],$file['name']);
             // 設定 POST 資料
            $data = array('file' => $cfile);
            curl_setopt($ch, CURLOPT_POST,1);
            curl_setopt($ch, CURLOPT_TIMEOUT, 60);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            // 執行控制代碼
            $id = curl_exec($ch);
            $error = curl_error($ch);
            curl_close($ch);
            if ($error) {
                throw new Exception('請求發生錯誤:' . $error);
            }
            ...
        }
    }

這個時候前端請求改介面,此介面向服務層進行post請求,實際的圖片上傳發生在應用層這個操作。

  • 服務層
public function uploadImg()
    {
        $attachment = new Attachment();
        $file = $_FILES['file'];
        $md5file = md5_file($file['tmp_name']);
        //該操作是判斷查詢是否上傳過相同圖片,如果有,就不再上傳,節省空間。
        //原理:使用md5_file() 函式計算檔案MD5 雜湊值,相同圖片的雜湊值相同,可避免同圖多次上傳,文字檔案也適用
        if ($res = $attachment->getFileByMd5($md5file)) {
            $id = $res->id;
            return $id;
        } else {
            $tmp = $file['tmp_name'];
            $path = date('Y-m-d',time());
            if (! file_exists ( "./abc/".$path )) {
                mkdir ( "./abc/".$path, 0777, true );
            }
            $filepath = './abc/'.$path;
            $temp = explode(".", $file['name']);
            $extension = '.'.end($temp);        // 獲取檔案字尾名
            $savename = md5(uniqid());
            if(move_uploaded_file($tmp,$filepath.'/'.$savename.$extension)){
                //可以將圖片相關資訊儲存到資料庫
                //這裡你也可以直接上傳到一些當下比較好用的儲存服務商,像七牛雲等。也是非常方便
            }
        }

    }

以上就是CURL的一些基礎使用方法。歡迎交流 ^_^