CURL的使用及上傳圖片
阿新 • • 發佈:2018-11-20
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的一些基礎使用方法。歡迎交流 ^_^