EasyWeChat 6.x 是目前 PHP 社区中最好用、最活跃的微信开发 SDK。

EasyWeChat 6.x (由 w7corp 维护) 相较于 5.x 版本,在配置和调用方式上有了很大的变化,它全面拥抱了 Factory (工厂) 模式和依赖注入,代码更现代化。

这里是一份为你准备的、基于 EasyWeChat 6.x微信服务号小程序开发的说明文档与 Demo。


说明文档:EasyWeChat 6.x 对接指南

1. 环境准备 (Prerequisites)
  1. PHP 版本EasyWeChat 6.x 要求 PHP >= 8.0
  2. Composer:用于安装 SDK。
  3. 微信资质
    • 服务号 (Official Account):已认证的服务号 AppID 和 AppSecret。
    • 小程序 (Mini Program):小程序 AppID 和 AppSecret。
  4. 开放平台 (Open Platform)
    • (关键) 如果你希望服务号和小程序下的用户身份是统一的(即获取到相同的 UnionID),你必须将此服务号和此小程序绑定到同一个微信开放平台账号下。
2. 安装 (Installation)

在你的项目根目录下,使用 Composer 执行:

composer require w7corp/easywechat:^6.0
3. 核心配置 (Configuration)

EasyWeChat 6.x 的核心是 Factory。你需要分别为服务号和小程序创建实例。

最佳实践:创建一个专门的配置文件(例如 config.php)来存放你的密钥,然后在应用中加载它。

示例 config.php (存放密钥)
<?php
// config.php
return [
    /**
     * 服务号配置
     */
    'official_account' => [
        'app_id' => '你的服务号AppID',
        'secret' => '你的服务号AppSecret',
        'token' => '你的服务号Token (用于服务器验证)',
        'aes_key' => '你的服务号EncodingAESKey (明文模式可不填)',
    ],

    /**
     * 小程序配置
     */
    'mini_app' => [
        'app_id' => '你的小程序AppID',
        'secret' => '你的小程序AppSecret',
    ],

    /**
     * 共享配置 (日志、HTTP等)
     */
    'common' => [
        // 日志配置
        'log' => [
            'default' => 'daily', // 默认日志驱动
            'channels' => [
                'daily' => [
                    'driver' => 'daily',
                    'path' => __DIR__ . '/logs/wechat.log', // 日志文件路径
                    'level' => 'debug',
                    'days' => 7,
                ],
            ],
        ],

        // HTTP 客户端配置
        'http' => [
            'timeout' => 5.0,
            'connect_timeout' => 5.0,
            // 更多配置...
        ],
    ]
];
示例 init.php (应用初始化)

在你的项目入口文件或一个公共的初始化文件(如 init.php)中,引入 Factory 并创建应用实例。

<?php
// init.php
require_once __DIR__ . '/vendor/autoload.php';

use EasyWeChat\Factory;

// 1. 加载配置
$config = require __DIR__ . '/config.php';

// 2. 创建服务号 App 实例
// 合并通用配置
$officialAccountConfig = array_merge($config['common'], $config['official_account']);
$oa = Factory::officialAccount($officialAccountConfig);

// 3. 创建小程序 App 实例
// 合并通用配置
$miniAppConfig = array_merge($config['common'], $config['mini_app']);
$mini = Factory::miniApp($miniAppConfig);

// 4. (可选) 将 $oa 和 $mini 实例存放到全局变量、DI容器或在需要的地方直接返回
// return ['oa' => $oa, 'mini' => $mini];

Demo:文件结构与代码示例

我们基于上述配置,创建以下文件结构来演示几个核心功能:

/your_project
|-- vendor/                 (Composer 目录)
|-- logs/                   (日志目录,需可写)
|-- config.php              (上面写的配置文件)
|-- init.php                (上面写的初始化文件)
|
|-- official_account/         (服务号功能)
|   |-- oauth_redirect.php  (1. 发起网页授权)
|   |-- oauth_callback.php  (2. 授权回调处理)
|   |-- server.php          (3. 消息与事件接收)
|
|-- mini_program/           (小程序功能)
|   |-- login.php           (1. 小程序登录凭证校验)
|   |-- decrypt.php         (2. 手机号等信息解密)
|
|-- composer.json

[Demo 1] 微信服务号 (Official Account) 功能

功能 1 & 2:网页授权 (OAuth 2.0 获取用户信息)

第1步:发起授权 official_account/oauth_redirect.php
(用户访问这个页面,将自动跳转到微信授权页)

<?php
// official_account/oauth_redirect.php

// 引入初始化文件,获取 $oa 实例
require_once __DIR__ . '/../init.php'; 
// $oa 已在 init.php 中被创建

// 准备回调地址 (必须是你在服务号后台配置的 "网页授权域名" 下的地址)
$callbackUrl = 'https://your-domain.com/official_account/oauth_callback.php';

// 获取 OAuth 实例
$oauth = $oa->getOauth();

// 1. 发起授权
// scope: snsapi_userinfo (弹框授权,可获取昵称头像)
// scope: snsapi_base (静默授权,只能获取 OpenID)
$response = $oauth->scopes(['snsapi_userinfo'])->redirect($callbackUrl);

// 6.x 版本中,redirect() 返回的是一个 PSR-7 Response 对象
// 我们需要 "发送" 这个响应,它会自动执行 302 跳转
$response->send();

第2步:处理回调 official_account/oauth_callback.php
(用户在微信上同意授权后,会携带 code 跳转回这个页面)

<?php
// official_account/oauth_callback.php
require_once __DIR__ . '/../init.php';

try {
    // 获取 OAuth 实例
    $oauth = $oa->getOauth();

    // 2. 通过 code 换取 AccessToken 和 OpenID
    // 注意:这里的 user() 方法会自动处理 $_GET['code']
    $user = $oauth->user();

    // 3. 获取用户信息
    // $user 是一个 EasyWeChat\Oauth\User 对象
    $originalData = $user->getOriginal(); // 原始数据
    $openId = $user->getId(); // OpenID
    $nickname = $user->getNickname(); // 昵称
    $avatar = $user->getAvatar(); // 头像
    $unionId = $user->getUnionId(); // UnionID (如果已绑定开放平台)

    // 业务逻辑:
    // 1. 在这里查询你的数据库,看 $openId 或 $unionId 是否已存在
    // 2. 如果不存在,创建新用户;如果存在,更新用户信息
    // 3. 登录态(Session/JWT)下发

    echo "授权成功!<br>";
    echo "OpenID: " . $openId . "<br>";
    echo "昵称: " . $nickname . "<br>";
    echo "头像: <img src='" . $avatar . "' width='100' /><br>";
    if ($unionId) {
        echo "UnionID: " . $unionId;
    }

} catch (\EasyWeChat\Exceptions\HttpException $e) {
    echo "授权失败:" . $e->getMessage();
} catch (\Throwable $e) {
    echo "系统错误:" . $e->getMessage();
}
功能 3:消息与事件接收 official_account/server.php

(你需要将 https://your-domain.com/official_account/server.php 填入服务号后台的 “服务器配置” URL)

<?php
// official_account/server.php
require_once __DIR__ . '/../init.php';
use EasyWeChat\Messages\Text;
use EasyWeChat\Messages\Image;

try {
    // 获取 Server 实例
    $server = $oa->getServer();

    // 1. 处理文本消息
    $server->with(function ($message, $next) {
        if ($message->MsgType === 'text') {
            // 根据关键词回复
            if ($message->Content === '你好') {
                return new Text('你也好!');
            }
            if ($message->Content === '图片') {
                // 回复图片 (MediaId 需要提前上传)
                // return new Image('MEDIA_ID_HERE');
            }
            // 默认回复
            return new Text('已收到你的消息:' . $message->Content);
        }
        return $next($message);
    });

    // 2. 处理事件 (如:关注)
    $server->with(function ($message, $next) {
        if ($message->MsgType === 'event') {
            if ($message->Event === 'subscribe') {
                return new Text('感谢你的关注!');
            }
            if ($message->Event === 'CLICK' && $message->EventKey === 'MENU_KEY_ABOUT_US') {
                return new Text('我们是 EasyWeChat 演示团队。');
            }
        }
        return $next($message);
    });

    // 3. 启动服务,处理请求
    $response = $server->serve();

    // 4. 发送响应
    $response->send();

} catch (\Throwable $e) {
    // 记录异常日志,非常重要!
    $log = $oa->getLogger();
    $log->error('Server Error: ' . $e->getMessage());
}

[Demo 2] 微信小程序 (Mini Program) 功能

功能 1:小程序登录 (code 换 session_key)

(小程序前端 wx.login() 成功后,会带着 code 请求这个接口)

<?php
// mini_program/login.php
require_once __DIR__ . '/../init.php';

// 设置响应头为 JSON
header('Content-Type: application/json');

// 1. 从前端获取 code
$payload = json_decode(file_get_contents('php://input'), true);
$code = $payload['code'] ?? ($_POST['code'] ?? $_GET['code']);

if (empty($code)) {
    echo json_encode(['errcode' => 400, 'errmsg' => 'code is required']);
    exit;
}

try {
    // 2. (推荐) 使用 $mini->get('auth') 获取 auth 实例
    $auth = $mini->get('auth');
    
    // 3. 调用 codeToSession (v6 的新方法)
    $session = $auth->session($code);
    
    // $session 是一个数组,例如:
    // [
    //   'openid' => 'OPENID',
    //   'session_key' => 'SESSION_KEY',
    //   'unionid' => 'UNIONID' (如果已绑定开放平台)
    // ]

    // 4. 业务逻辑
    // (重要) 不要把 session_key 返回给前端!
    // 1. 根据 openid 和 unionid 查询或创建用户
    // 2. 生成你自己的登录态 (例如 JWT 或 Token)
    // 3. 将 Token 和 openid (或 unionid) 返回给前端

    // 示例:仅返回 openid 和 unionid
    $responseData = [
        'errcode' => 0,
        'errmsg' => 'ok',
        'openid' => $session['openid'],
        'unionid' => $session['unionid'] ?? null,
        'my_token' => 'YOUR_CUSTOM_LOGIN_TOKEN_HERE', // (这是你生成的Token)
    ];
    echo json_encode($responseData);

} catch (\EasyWeChat\Exceptions\HttpException $e) {
    // API 请求失败
    echo json_encode(['errcode' => $e->getCode(), 'errmsg' => $e->getMessage()]);
} catch (\Throwable $e) {
    // 其他错误
    echo json_encode(['errcode' => 500, 'errmsg' => 'server error']);
}
功能 2:解密用户信息 (如手机号)

(小程序前端通过 button open-type="getPhoneNumber" 获取 codeivencryptedData,然后传给后端)

<?php
// mini_program/decrypt.php
require_once __DIR__ . '/../init.php';

header('Content-Type: application/json');

$payload = json_decode(file_get_contents('php://input'), true);

// 1. 获取前端数据
$code = $payload['code'] ?? null; // 这是 getPhoneNumber 用的 code
$iv = $payload['iv'] ?? null;
$encryptedData = $payload['encrypted_data'] ?? null;

if (empty($code) || empty($iv) || empty($encryptedData)) {
    echo json_encode(['errcode' => 400, 'errmsg' => 'missing required parameters']);
    exit;
}

try {
    // 2. (重要) 解密手机号需要用 session_key
    // EasyWeChat v6 提供了快捷方法,它会自动用 code 换 session_key,然后再解密
    
    $utils = $mini->getUtils();
    
    // 3. 解密手机号 (v6.10+ 新增)
    $phoneData = $utils->getPhone($code, $encryptedData, $iv);
    
    // $phoneData 示例:
    // [
    //   'phoneNumber' => '13800138000',
    //   'purePhoneNumber' => '13800138000',
    //   'countryCode' => '86',
    //   'watermark' => [ 'appid' => '...', 'timestamp' => ... ]
    // ]

    // 业务逻辑:将手机号 $phoneData['purePhoneNumber'] 绑定到对应用户

    echo json_encode([
        'errcode' => 0,
        'errmsg' => 'ok',
        'phone_info' => $phoneData,
    ]);

} catch (\Exception $e) {
    echo json_encode(['errcode' => 500, 'errmsg' => '解密失败: ' . $e->getMessage()]);
}
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐