文章大纲

php里使用curl实现多张图片的上传

2019-08-29 22:59:45
最近接触到需要识别验证码的功能,由于网站里获取验证码的请求的返回值就是验证码图片的base64码,所以就想着直接通过base64码上传图片到第三方识别验证码的平台,而不用先去保存为图片到自己服务器上,然后再去读取上传,省得验证码图片占用服务器磁盘空间。

以前开发页面form表单提交图片时,大概如下所示:
//upload.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
</head>
<body>
<form method="post" action="upload_pic.php" enctype="multipart/form-data">
<input type="file" name="zhaipic" >
<button type="submit">提交</button>
</form>
<body>
后端接收图片数据的文件,打印$_FILES数组,内容大概如下:
//upload_pic.php
var_dump($_FILES);

//下面是打印结果
'zhaipic' =>
array (size=5)
'name' => string '20190707-工作之后.jpg' (length=25)
'type' => string 'image/jpeg' (length=10)
'tmp_name' => string 'E:\wamp64\tmp\php1CAB.tmp' (length=25)
'error' => int 0
'size' => int 70708

看firefox提交数据,大概就是如下图所示格式,图片字节流显示一大堆乱码。


本文为翟码农的个人博客蓝翟红尘上的PHP分类下的原创文章,转载请注明出处:http://www.zhai14.com/blog/c305ad05330022c58f688411b5831701.html

现在要做的,就是使用curl方法,提交图片base64码到后端,后端打印$_FIELS要能够像上面一样获取图片文件的数据。
其实思想,主要就是模拟像上面firefox提交的请求数据,请见下面代码中的buildPostData方法。
//curl.php
function buildPostData($fields, $files){
global $delimiter;
$data = '';
$eol = "\r\n";
    //form表单栏位部分
foreach ($fields as $name => $content) {
$data .= "--" . $delimiter . $eol
. 'Content-Disposition: form-data; name="' . $name . "\"".$eol.$eol
. $content . $eol;
}
    //图片及文件部分
foreach ($files as $name => $content) {
$data .= "--" . $delimiter . $eol
. 'Content-Disposition: form-data; name="' . $name . '"; filename="' . $name . '"' . $eol
. 'Content-Transfer-Encoding: binary'.$eol
;

$data .= $eol;
$data .= $content . $eol;
}
$data .= "--" . $delimiter . "--".$eol;
return $data;
}

//要提交的栏位
$fields = array("param_a"=>"blue", "param_b"=>"zhai");

//要上传的图片或文件,这里我准备了两张,
//banner和logo是我打算上传给后端接收的图片名称,你可以自己随便命名
$filenames = array("banner" => "./img/1111.jpg", "logo"=>"./img/logo.png");

$files = array();
foreach ($filenames as $key => $f){
//这里通过本地图片提供图片字节流,方便测试
$files[$key] = file_get_contents($f);
}

$postUrl = "http://localhost/study/upload_pic.php";


$boundary = uniqid();
$delimiter = '-------------' . $boundary;

$postData = buildPostData($fields, $files);



$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $postUrl);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($curl, CURLOPT_POST, 1);
//post提交的数据
file_put_contents('./php.log', $postData);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);

$header = array(
"Content-Type: multipart/form-data; boundary=" . $delimiter,
"Content-Length: " . strlen($postData)
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
//执行命令
$data = curl_exec($curl);
//关闭URL请求
curl_close($curl);
再修改下upload_pic.php文件,保存下提交数据,以验证代码是否达到目的。
//upload_pic.php

file_put_contents('./php.log', json_encode($_FILES), FILE_APPEND);
file_put_contents('./php.log', json_encode($_POST), FILE_APPEND);

执行curl.php脚本,观察php.log文件内容,前一部分是提交的请求数据。
为了简化数据,图片字节流,我已采用$符号表示。
---------------5d67de098efad
Content-Disposition: form-data; name="param_a"

blue
---------------5d67de098efad
Content-Disposition: form-data; name="param_b"

zhai
---------------5d67de098efad
Content-Disposition: form-data; name="banner"; filename="banner"
Content-Transfer-Encoding: binary

$$$$$$$$$$$$
xmpMM:DocumentID="xmp.did:C41EC82665A0E911967BC81D2C4522BA" xmpMM:OriginalDocumentID="xmp.did:C41EC82665A0E911967BC81D2C4522BA"> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>06AA88309DBA22780EA7C96F063C11D3</rdf:li> <rdf:li>xmp.did:C41EC82665A0E911967BC81D2C4522BA</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:C41EC82665A0E911967BC81D2C4522BA" stEvt:when="2019-07-07T12:01:17+08:00" stEvt:softwareAgent="Adobe Photoshop CS6 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:4A8B56D26FA0E911AC288EE015B7B6EE" stEvt:when="2019-07-07T13:08:06+08:00" stEvt:softwareAgent="Adobe Photoshop CS6 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:A05E554075A0E911AC288EE015B7B6EE" stEvt:when="2019-07-07T13:09:33+08:00" stEvt:softwareAgent="Adobe Photoshop CS6 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:A15E554075A0E911AC288EE015B7B6EE" stEvt:when="2019-07-07T13:09:33+08:00" stEvt:softwareAgent="Adobe Photoshop CS6 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:A05E554075A0E911AC288EE015B7B6EE" stRef:documentID="xmp.did:C41EC82665A0E911967BC81D2C4522BA" stRef:originalDocumentID="xmp.did:C41EC82665A0E911967BC81D2C4522BA"/> </rdf:Description> </rdf:RDF> </x:xmpmeta>
$$$$$$$$$$$$
---------------5d67de098efad
Content-Disposition: form-data; name="logo"; filename="logo"
Content-Transfer-Encoding: binary

$$$$$$$$$$$$
---------------5d67de098efad--
话外:这里偶然发现图片字节流里还能看到我这张图片是photoshop制作的数据信息。

再看提交到upload_pic.php文件保存的数据:
{"banner":{"name":"banner","type":"","tmp_name":"E:\\wamp64\\tmp\\phpC287.tmp","error":0,"size":60074},
"logo":{"name":"logo","type":"","tmp_name":"E:\\wamp64\\tmp\\phpC288.tmp","error":0,"size":13392}}

{"param_a":"blue","param_b":"zhai"}
看$_FILES变量数据格式,正与上面form表单提交到后端的数据格式一致,所以本文的目标已实现成功。







我要评论
评论列表