企业微信"上传临时素材"https://developer.work.weixin.qq.com/document/path/91853

重点:发起发起 multipart/form-data 格式的 POST 请求上传文件,且文件标识名为 media
php
public function qyweixinUpload()
{
try {
// 模拟文件信息(实际场景可能从前端接收)
$file = [
'url' => '/uploads/20221129/ec53e727c226d573f9a211fb228630fc.xlsx',
'name' => '28630fc.xlsx'
];
// 1. 拼接完整文件路径并校验格式
$filePath = ROOT_PATH . 'public' . $file['url'];
// 校验路径是否合法(避免目录遍历攻击)
if (strpos(realpath($filePath), realpath(ROOT_PATH . 'public')) === false) {
throw new \Exception("文件路径不合法:{$filePath}");
}
// 2. 校验文件是否存在
if (!file_exists($filePath)) {
throw new \Exception("文件不存在:{$filePath}");
}
// 3. 校验文件是否可读
if (!is_readable($filePath)) {
throw new \Exception("文件不可读(权限不足):{$filePath}");
}
// 4. 校验文件大小(企业微信普通文件限制20MB)
$fileSize = filesize($filePath);
$maxSize = 20 * 1024 * 1024; // 20MB
if ($fileSize <= 5) {
throw new \Exception("所有文件大小必须大于5个字节");
}
if ($fileSize > $maxSize) {
throw new \Exception("文件过大(当前:" . round($fileSize / 1024 / 1024, 2) . "MB,最大支持:20MB)");
}
// 5. 校验文件类型(通过后缀或MIME类型)
$allowExts = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'zip']; // 允许的后缀
$fileExt = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
if (!in_array($fileExt, $allowExts)) {
throw new \Exception("不支持的文件类型(当前:.{$fileExt},允许:." . implode(', .', $allowExts) . ")");
}
// 6. 获取MIME类型(兼容无fileinfo扩展的情况)
$mimeType = 'application/octet-stream'; // 默认类型
if (class_exists('finfo')) {
$finfo = new \finfo(FILEINFO_MIME_TYPE);
$mimeType = $finfo->file($filePath);
} else {
// 手动映射常见MIME类型(无fileinfo扩展时)
$mimeMap = [
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'pdf' => 'application/pdf',
'zip' => 'application/zip',
// 补充其他类型
];
$mimeType = $mimeMap[$fileExt] ?? $mimeType;
}
// 后续企业微信上传逻辑...
$fileName = $file['name'];
$accessToken = wecomService::getAccessToken();
$uploadUrl = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token={$accessToken}&type=file";
$ch = curl_init();
$data = [
'media' => new \CURLFile($filePath, $mimeType, $fileName)
];
curl_setopt($ch, CURLOPT_URL, $uploadUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
// 处理上传结果...
if (isset($result['errcode']) && $result['errcode'] == 0) {
return json([
'code' => 1,
'msg' => '上传成功',
'data' => [
'media_id' => $result['media_id'],
'type' => $result['type'],
'created_at' => $result['created_at']
]
]);
} else {
return json(['code' => 0, 'msg' => "企业微信上传失败:{$result['errmsg']}"]);
}
} catch (\Exception $e) {
return json(['code' => 0, 'msg' => $e->getMessage()]);
}
}
上述方法中,需要开启PHP的扩展fileinfo
开启方法参考如下图(宝塔面板),也可以修改php配置文件,这里不详细赘述
