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

相关推荐
南_山无梅落12 分钟前
9.Python3集合(set)增删改查和推导式
java·开发语言
sg_knight27 分钟前
拥抱未来:ECMAScript Modules (ESM) 深度解析
开发语言·前端·javascript·vue·ecmascript·web·esm
程序喵大人42 分钟前
推荐个 C++ 练习平台
开发语言·c++·工具推荐
阿里嘎多学长1 小时前
2025-12-16 GitHub 热点项目精选
开发语言·程序员·github·代码托管
乂爻yiyao1 小时前
Java LTS版本重要升级特性对照表
java·开发语言
原来是好奇心1 小时前
深入Spring Boot源码(六):Actuator端点与监控机制深度解析
java·开发语言·源码·springboot
过期动态2 小时前
JDBC高级篇:优化、封装与事务全流程指南
android·java·开发语言·数据库·python·mysql
WizLC2 小时前
【Java】各种IO流知识详解
java·开发语言·后端·spring·intellij idea
傻啦嘿哟2 小时前
实战:用Splash搞定JavaScript密集型网页渲染
开发语言·javascript·ecmascript
Knight_AL2 小时前
Java 线程池预热(Warm-up)实战:开启与不开启到底差多少?
java·开发语言