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配置文件,这里不详细赘述

相关推荐
Mr -老鬼9 分钟前
Rust适合干什么?为什么需要Rust?
开发语言·后端·rust
予枫的编程笔记12 分钟前
【Java集合】深入浅出 Java HashMap:从链表到红黑树的“进化”之路
java·开发语言·数据结构·人工智能·链表·哈希算法
ohoy18 分钟前
RedisTemplate 使用之Set
java·开发语言·redis
mjhcsp18 分钟前
C++ 后缀数组(SA):原理、实现与应用全解析
java·开发语言·c++·后缀数组sa
hui函数19 分钟前
如何解决 pip install 编译报错 ‘cl.exe’ not found(缺少 VS C++ 工具集)问题
开发语言·c++·pip
云栖梦泽28 分钟前
易语言Windows桌面端「本地AI知识管理+办公文件批量自动化处理」双核心系统
开发语言
r_oo_ki_e_38 分钟前
java22--常用类
java·开发语言
AI小怪兽41 分钟前
轻量、实时、高精度!MIE-YOLO:面向精准农业的多尺度杂草检测新框架 | MDPI AgriEngineering 2026
开发语言·人工智能·深度学习·yolo·无人机
码农小韩41 分钟前
基于Linux的C++学习——循环
linux·c语言·开发语言·c++·算法
消失的旧时光-19431 小时前
C++ 命名空间 namespace 讲透:从 std:: 到工程实践
开发语言·c++