php上传企业微信附件的方法

企业微信"上传临时素材"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配置文件,这里不详细赘述

相关推荐
暮乘白帝过重山3 小时前
ArkTS ForEach 参数解析:组件与键值生成器
开发语言·数据库
LiamTuc3 小时前
Java构造函数
java·开发语言
三途河畔人4 小时前
Pytho基础语法_运算符
开发语言·python·入门
Benmao⁢4 小时前
C语言期末复习笔记
c语言·开发语言·笔记·leetcode·面试·蓝桥杯
adsadswee4 小时前
Qt 样式与 QLinearGradient 渐变详解
开发语言·qt·qt样式表·qlineargradient·qss渐变效果
花月C4 小时前
个性化推荐:基于用户的协同过滤算法
开发语言·后端·算法·近邻算法
脾气有点小暴4 小时前
前端页面跳转的核心区别与实战指南
开发语言·前端·javascript
rit84324995 小时前
基于MATLAB的BP神经网络手写数字识别
开发语言·神经网络·matlab
San30.5 小时前
深入 JavaScript 内存机制:从栈与堆到闭包的底层原理
开发语言·javascript·udp
灰灰勇闯IT6 小时前
RN路由与状态管理:打造多页面应用
开发语言·学习·rn路由状态