PHP 可以使用 file_get_content() 函數抓取網頁內容,但卻無法進行更複雜的處理,如檔案的上傳或下載、 Cookie 操作等等。而 PHP 的 cURL 提供了這些功能。
cURL 是 PHP 的一個擴充函式庫。它可以與各種類型的伺服器、使用各種類型的協定進行連接和通訊。
它目前支援 http、https、ftp、gopher、telnet、dict、file 和 ldap 協議,同時也支援 HTTPS 認證、HTTP POST、 FTP 上傳、代理、cookies 和 使用者名稱 + 密碼的認證等。
常用函數
函數 | 說明 |
curl_init() | 初始化cURL 會話 |
curl_setopt() | # 設定cURL 選項 |
curl_exec() |
# 執行cURL 會話 |
取得目前會話資訊 | |
# 傳回最後一次的錯誤碼 | |
傳回目前會話最後一次的錯誤字串 | |
關閉cURL 會話 |
# 其他函數 | |
函數 | |
curl_copy_handle() | |
curl_escape() | |
curl_file_create() | |
curl_multi_add_handle() | |
curl_multi_close() | |
curl_multi_exec() | |
curl_multi_getcontent() | |
curl_multi_info_read() | |
curl_multi_init() | |
curl_multi_remove_handle() | |
curl_multi_select() | |
curl_multi_setopt() | |
curl_multi_strerror() | |
curl_pause() | |
curl_reset() | |
curl_setopt_array() | |
curl_share_close() | |
curl_share_init() | |
curl_share_setopt() | |
curl_strerror() | |
curl_unescape() |
1.初始化cURL 會話
#2. 設定cURL 選項
3. 執行cURL 會話
4 . 取得cURL 資訊和(或)錯誤訊息(這一步可以沒有)
5. 關閉cURL 句柄
這裡面最複雜的是第2 步,cURL 的設定選項有很多,下面會結合實例來了解。
GET 請求的流程就是 cURL 的一般流程。
在本機伺服器 localserver.com 根目錄準備一個測試腳本 index.php,內容如下:
<?php $url = 'http://www.baidu.com'; // 初始化,获得一个cURL句柄 $ch = curl_init(); // 设置选项 curl_setopt($ch, CURLOPT_URL, $url); // 请求URL curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据流,而不直接输出 curl_setopt($ch, CURLOPT_HEADER, 0); // 无需响应的header头 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); //连接超时,秒为单位 // 执行并获取返回内容 $output = curl_exec($ch); if($output === false){ $output = 'cURL error: ' . curl_error($ch); } // 释放 cURL 句柄资源 curl_close($ch); print_r($output); ?>
瀏覽器存取本機伺服器首頁 localserver.com/index.php,顯示百度首頁。
POST 請求需要設定兩個選項:
curl_setopt($ch, CURLOPT_POST, 1); // 表明POST请求 curl_setopt($ch, CURLOPT_POSTFIELDS, $postData)); // POST提交数据
先在遠端伺服器remoteserver.com 根目錄準備一個用於接收的腳本index.php,內容如下:
<?php $input = file_get_contents('php://input'); echo $input; ?>
然後在本機伺服器localserver.com 根目錄來寫用於POST 請求的腳本index.php,內容如下:
<?php $url = 'http://remoteserver.com/index.php'; $data = array( 'fname'=> 'Daniel', 'lname' => 'Stenberg' ); // 初始化 $ch = curl_init(); // 设置选项 curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($ch, CURLOPT_POST, 1); // POST请求 curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); //POST数据。用http_build_query()转换为“&”拼接的字符串 // 执行并获取返回内容 $output = curl_exec($ch); if($output === false){ $output = 'cURL error: ' . curl_error($ch); } // 释放 cURL 句柄资源 curl_close($ch); print_r($output); ?>
瀏覽器存取 localserver. com/index.php,顯示如下:
fname=Daniel&lname=Stenberg
cURL 上傳檔案的想法是:在檔案路徑的前面加上"@"符號,並裝在請求字段裡實現上傳。後台可以透過 $_FILES 取得上傳檔案資訊。但 PHP5.6 以後,廢除了"@"符號,可以使用 CURLFile 類別實作上傳。
先在遠端伺服器remoteserver.com 根目錄準備一個用於接收的腳本index.php,內容如下:
<?php $action = $_POST['action']; if($action == 'uploadImage'){ $name = $_FILES['file']['name']; $tmpname = $_FILES['file']['tmp_name']; // 保存到当前脚本所在目录 move_uploaded_file($tmpname, dirname(__FILE__).'/'.$name); $error = $_FILES['file']['error']; switch ($error) { case 0: echo '上传成功'; break; case 1: echo '文件大小超出 php.ini 限制'; break; case 2: echo '文件大小超出 表单 MAX_FILE_SIZE 限制'; break; case 3: echo '文件部分被上传'; break; case 4: echo '没有文件被上传'; break; case 6: echo '找不到临时文件夹'; break; case 7: echo '文件写入失败'; break; default: $output = '未知错误'; } } ?>
然後在本地伺服器localserver.com 根目錄準備一個圖片檔案test .jpg 與cURL 上傳腳本index.php, 腳本內容如下:
<?php $url = 'http://remoteserver.com/index.php'; $file = realpath(getcwd() . '/test.jpg'); $data = array( 'action' => 'uploadImage', 'file' => '@' . $file ); if(version_compare(PHP_VERSION, '5.6.0') > 0){ $data['file'] = new CURLFile($file); } // 初始化 $ch = curl_init(); // 设置选项 curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // 执行并获取返回内容 $output = curl_exec($ch); if($output === false){ $output = 'cURL error: ' . curl_error($ch); } // 释放 cURL 句柄资源 curl_close($ch); print_r($output); ?>
瀏覽器存取 localserver.com/index.php,顯示如下:
上传成功
查看遠端伺服器根目錄,發現多了一張剛才上傳的圖片。
cURL 下載檔案的一個想法是:設定cURL 選項CURLOPT_FILE 為一個檔案指針,以此將要求的資源檔案關聯到一個檔案流裡,這個檔案流一般是fopen()函數的回傳值。使用檔案流將遠端檔案寫到本地,可以避免寫(下載)大檔案時可能的記憶體出錯。
在本機伺服器localserver.com 根目錄來寫測試腳本index.php,內容如下:
<?php $url = 'http://remoteserver.com/test.jpg'; $file = './test.jpg'; $fp = fopen($file, 'w'); // 初始化 $ch = curl_init(); // 设置选项 curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($ch, CURLOPT_FILE, $fp); // 用于传输的文件流,默认是STDOUT // 执行并获取返回内容 $output = curl_exec($ch); if($output === false){ $output = 'cURL error: ' . curl_error($ch); } // 获取已下载大小 $size_download = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD); // 释放资源 fclose($fp); curl_close($ch); if ($size_download && $size_download == filesize($file)) { echo "下载成功"; } else { echo "下载失败或不完整"; } ?>
瀏覽器存取localserver.com/index.php,顯示如下:
下载成功
查看本機伺服器根目錄,發現下載到了遠端的圖片。
cURL 有一個批次句柄,透過開啟多個cURL 句柄,並將這些句柄綁定到一個批次句柄,然後在循環中依次處理每個cURL 連接,可以實現非同步的批次,類似「多執行緒」。
在本機伺服器localserver.com 根目錄來寫測試腳本index.php,內容如下:
<?php $urls = array( 'http://www.baidu.com', 'http://www.qidian.com' ); $count = count($urls); $ch = array(); // 创建批处理cURL句柄 $mh = curl_multi_init(); // 初始化每个cURL,并设置选项,绑定给批处理句柄 for ($i = 0; $i < $count; $i++) { $ch[$i] = curl_init(); curl_setopt($ch[$i], CURLOPT_URL, $urls[$i]); curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch[$i], CURLOPT_HEADER, 0); curl_setopt($ch[$i], CURLOPT_CONNECTTIMEOUT, 30); curl_multi_add_handle($mh, $ch[$i]); } // 执行批处理 $running = null; do { usleep(10000); // 延迟0.01秒,单位为百万分之一秒 curl_multi_exec($mh, $running); // 异步实现批处理,类似“多线程” } while($running > 0); // 获取每个cURL的响应 $res = array(); for ($i = 0; $i < $count; $i++) { $res[$i] = curl_multi_getcontent($ch[$i]); } // 关闭全部句柄 for ($i = 0; $i < $count; $i++) { curl_multi_remove_handle($mh, $ch[$i]); } curl_multi_close($mh); print_r($res); ?>
瀏覽器存取localserver.com/index.php,顯示「連線」的百度首頁和起點網首頁。
以上是php中比file_get_contents()更優的cURL的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!