上传临时素材和永久素材(不包含图文素材)除了接口名其他几乎是一样的,上传素材接口和其他接口最大区别在于post的数据是数组形式而不是json或字符串,所以如果你用其他接口的curl方法去请求肯定是会报错的,所以需要单独封装一个curl请求方法,
如果是上传图片,语音,缩略图素材的话可以这样封装一个方法:
//$filePath 文件的绝对路径如 D:\www\img\f01167c410d08104df62ad58d0086a66.jpg
public function mediaUpload($type,$filePath,$mode='media_upload'){
$php_version=substr(PHP_VERSION,0,3);
if($php_version>5.5){
$postData=[
'media'=>new \CURLFile($filePath),
];
}else{
$postData=[
'media'=>'@'.$filePath
];
}
//这里的url是一接口的请求地址,我这里是根据参数动态拼接的url
$url=$this->weixinApiLinks[$mode]."access_token={$this->access_token}&type=".$type;
$calldata=json_decode($this->https_request($url,$postData),true);
return $calldata;
}
public function https_request($url, $data = null){
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
PHP的cURL支持通过给CURL_POSTFIELDS传递关联数组(而不是字符串)来生成multipart/form-data的POST请求,PHP的cURL支持通过在数组数据中,使用“@+文件绝对路径”的语法附加文件,供cURL读取上传,但PHP从5.5开始引入了新的CURLFile类用来指向文件,CURLFile类也可以详细定义MIME类型、文件名等可能出现在multipart/form-data数据中的附加信息,PHP 5.5另外引入了CURL_SAFE_UPLOAD选项,可以强制PHP的cURL模块拒绝旧的@语法,仅接受CURLFile式的文件。5.5的默认值为false,5.6的默认值为true,所以这里面我判断了php的版本来决定使用哪一种方法。
另外视频素材跟其他三个有一点区别是会附加一个表单

所以我这里在将前面的上传方法复制一个做一些修改来针对视频素材的上传:
public function mvUpload($type,$filePath,$mode='media_upload'){
$php_version=substr(PHP_VERSION,0,3);
if($php_version>5.5){
$postData=[
'media'=>new \CURLFile($filePath),
'description'=>'{"title":"ceshi mv","introduction":"hahahahhaha"}'
];
}else{
$postData=[
'media'=>'@'.$filePath,
'description'=>'{"title":"ceshi mv","introduction":"hahahahhaha"}'
];
}
$url=$this->weixinApiLinks[$mode]."access_token={$this->access_token}&type=".$type;
$calldata=json_decode($this->https_request($url,$postData),true);
return $calldata;
}
里面的描述和标题我是随便写s的,实际应用可通过传参来赋值,两个方式都测试过都可以上传成功