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()查看:
CURL的使用及上传图片_第1张图片
如果真的额没有开启的话,就到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。
//这个是正常的网页
提交表单时,浏览器发送的头部。 //而 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方式


// 创建一个新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请求,上个例子


    $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

  
    $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上传图片

下列上传图片的场景如下:
CURL的使用及上传图片_第2张图片
随手画了一下,大致是这个流程。

  • 应用层
    客户端上传就不细说了,这个例子是我简单写的一个,在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的一些基础使用方法。欢迎交流 ^_^

你可能感兴趣的:(PHP)