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 小时前
在 PHP 中打印数据(调试、输出内容)
php
起予者汝也3 小时前
Python基础入门
开发语言·python
芯联智造3 小时前
【stm32协议外设篇】- SU03T 智能语音模块
c语言·开发语言·stm32·单片机·嵌入式硬件
川石课堂软件测试3 小时前
Python | 高阶函数基本应用及Decorator装饰器
android·开发语言·数据库·python·功能测试·mysql·单元测试
lqqjuly3 小时前
Matlab2025a实现双目相机标定~业余版
开发语言·matlab·相机标定·双目相机
Brianna Home4 小时前
现代C++:从性能泥潭到AI基石
开发语言·c++·算法
2301_796512524 小时前
Rust编程学习 - 自动解引用的用处,如何进行“解引用”(Deref) 是“取引用”(Ref) 的反操作
开发语言·学习·rust
qq19257230274 小时前
c++特性
开发语言·c++·算法
weixin_307779134 小时前
AWS Elastic Beanstalk 实现 Java 应用高可用部署指南
java·开发语言·云计算·aws·web app