fcwh/ucentersdk-php

PHP SDK for UCenter User Center API - 第三方应用访问用户中心

Maintainers

Package info

github.com/yangxiaozhan/ucenter_sdk

pkg:composer/fcwh/ucentersdk-php

Statistics

Installs: 4

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-master 2026-03-01 07:28 UTC

This package is auto-updated.

Last update: 2026-03-01 07:35:13 UTC


README

PHP SDK for UCenter 用户中心,供第三方应用通过 API 访问同一用户中心(UCenter),实现用户注册、登录、资料、短消息、好友、积分、标签等能力。

接口规范基于项目内 document/ 目录中的 UCenter 接口开发手册(UCenter 2 及以上版本)。

对外使用文档docs/SDK使用文档.md — 面向第三方开发者的完整使用说明与接口说明。

环境要求

  • PHP >= 7.4
  • ext-json

安装

composer require fcwh/ucentersdk-php

富酬文化内部专用sdk

配置

  • 直连数据库(推荐):仅需数据库连接,不暴露接口,见下方「直连数据库」。
  • HTTP 模式:需 UCenter 服务端地址及 appid/secret。

使用说明

直连数据库(最少配置,无需暴露接口)

建表:mysql -u root -p 数据库名 < server/schema.sql,然后:

use UCenter\Sdk\UCenterClient;

$client = UCenterClient::fromDatabase([
    'host' => '127.0.0.1',
    'dbname' => 'ucenter',
    'username' => 'root',
    'password' => 'xxx',
]);
// 无需 baseUrl、appId、secret;仅支持用户 register/login/get_user/edit(含绑定)

也可传入 require 'server/config.php' 或环境变量(见 server/config.example.php)。

混合模式(推荐):主逻辑 UCenter,绑定关系存本地 DB

注册/登录/获取用户/编辑等全部走 UCenter 接口;仅绑定关系(手机/微信/微博/QQ ↔ 用户)存本地表 uc_bindings,便于按标识解析登录。

  1. 建表:执行 server/schema.sqlserver/schema_bindings_only.sql(至少要有 uc_bindings 表;解绑为软删除,表含 deleted_at 字段。已有表请执行 server/migration_add_deleted_at_to_uc_bindings.sql 升级)。
  2. 初始化:
use UCenter\Sdk\UCenterClient;

$client = UCenterClient::withBindingStore(
    'https://uc.example.com',   // UCenter 地址
    'your_appid',
    'your_secret',
    [ 'host' => '127.0.0.1', 'dbname' => 'ucenter', 'username' => 'root', 'password' => 'xxx' ]  // 绑定表所在库
);
// register/login/get_user/edit 走 UCenter;bind/unbind/getBindings 及 类型+标识 登录会读写本地 uc_bindings

初始化客户端(仅 HTTP 模式)

use UCenter\Sdk\UCenterClient;

$client = new UCenterClient(
    'https://uc.example.com',   // UCenter 根地址,不要带末尾斜杠
    'your_appid',
    'your_secret'
);

$client->setTimeout(15);

用户接口

// 用户注册(成功后自动与 uid=1 管理员互为好友,仅 HTTP/混合模式)
$uid = $client->user()->register('username', 'password', 'user@example.com');
// 可选:注册同时写入绑定(类型+标识),便于后续 类型+标识 登录先查绑定
$uid = $client->user()->register('username', 'password', 'user@example.com', 0, '', '', UserApi::LOGIN_TYPE_PHONE, '13800138000');
// $uid > 0 为成功(返回用户 ID),负数见文档错误码

// 用户登录(支持用户名+密码,或 类型+标识 自动注册登录)
$res = $client->user()->login('username', 'password');
// 类型+标识:第一参数为类型常量,第二参数为标识;未注册则自动注册后再登录
use UCenter\Sdk\Api\UserApi;
$res = $client->user()->login(UserApi::LOGIN_TYPE_PHONE, '13800138000');
$res = $client->user()->login(UserApi::LOGIN_TYPE_WECHAT_UNIONID, 'wx_unionid_xxx');
$res = $client->user()->login(UserApi::LOGIN_TYPE_WEIBO_OPENID, 'weibo_openid_xxx');
$res = $client->user()->login(UserApi::LOGIN_TYPE_QQ_UNIONID, 'qq_unionid_xxx');
// 第三参数起同原 login;类型+标识时可通过 options 传 email_domain、extra_profile
$res = $client->user()->login(UserApi::LOGIN_TYPE_PHONE, '13800138000', 0, false, 0, '', [
    'email_domain' => 'myapp.local',
    'extra_profile' => ['nickname' => '昵称'],
]);
// $res['status'] > 0 为成功(用户 ID),含 username、email 等;若已设置 JwtToken 则返回 access_token

// 用户绑定:一个账号绑定手机/微信/微博/QQ 后,可用任意一种方式登录同一账号
$client->user()->bind('username', UserApi::LOGIN_TYPE_PHONE, '13800138000');       // 绑定手机
$client->user()->bind('username', UserApi::LOGIN_TYPE_WECHAT_UNIONID, 'wx_unionid');
$client->user()->bind('username', UserApi::LOGIN_TYPE_WEIBO_OPENID, 'weibo_openid');
$client->user()->bind('username', UserApi::LOGIN_TYPE_QQ_UNIONID, 'qq_unionid');
$client->user()->unbind('username', UserApi::LOGIN_TYPE_PHONE);                    // 解绑手机
$bindings = $client->user()->getBindings('username');  // 查看已绑定:phone, wechat_unionid, weibo_openid, qq_union_id
// 说明:绑定后用该标识 login(类型, 标识) 登录到同一账号;解绑为软删除(不 DELETE,仅设置 deleted_at)

// 登录成功直接返回 access_token(JWT):设置 JwtToken 后,login 成功时自动签发并写入返回
use UCenter\Sdk\Jwt\JwtToken;
$client->setJwtToken(new JwtToken('your_jwt_secret', 7200));
$res = $client->user()->login('username', 'password');
// $res['access_token'] 为 JWT,可用于 Authorization: Bearer xxx
// 验证 token
$payload = $client->getJwtToken()->verify($res['access_token']);  // 含 sub、username、iat、exp 等
// 或手动颁发/验证
$jwt = new JwtToken('your_jwt_secret', 7200);
$token = $jwt->issue(['sub' => (string)$res['status'], 'username' => $res['username'] ?? '']);
$payload = $jwt->verify($token);

// 获取用户信息(含扩展字段:phone, wechat_unionid, nickname, avatar, qq_union_id, weibo_openid, douyin_openid, is_member 等)
$user = $client->user()->getUser('username');        // 按用户名
$user = $client->user()->getUser('123', true);       // 按 uid(第二参数 isuid=true)
// $user 为扁平数组,含 uid, username, email, phone, wechat_unionid, avatar, nickname 等

// 更新资料(需旧密码,或 ignoreoldpw=true);可传扩展字段
$client->user()->edit('username', $oldpw, $newpw, $email, false, 0, '', $phone, $wechat_openid, $wechat_unionid, ...);

// 仅更新扩展资料(无需旧密码)
$client->user()->updateProfile('username', ['phone' => '13800138000', 'nickname' => '昵称', 'avatar' => 'https://...', 'wechat_unionid' => 'xxx']);
$client->user()->setPhone('username', '13800138000');
$client->user()->setAvatar('username', 'https://example.com/avatar.jpg');   // 头像为 URL 字符串,由前置应用上传后传入
$client->user()->setWechatOpenid('username', 'openid_xxx');
$client->user()->setWechatUnionid('username', 'unionid_xxx');
$client->user()->setNickname('username', '昵称');
$client->user()->deleteAvatar($uid);   // 清空头像 URL 记录

// 删除用户
$client->user()->delete(123);           // 单个 uid
$client->user()->delete([123, 456]);   // 多个 uid

// 授权登录:获取授权页地址
$auth = $client->user()->authorize('https://yourapp.com/callback');
// 跳转 $auth['url'],回调里用 code 调 checkCode

// 验证回调 code,换取用户
$info = $client->user()->checkCode($_GET['code']);
// $info['ret']==0 时,$info['uid'], $info['username'] 可用

// 同步登录 / 同步退出(返回需输出到页面的 HTML)
$html = $client->user()->synLogin($uid);
$html = $client->user()->synLogout();

// 检查用户名、邮箱是否可用
$client->user()->checkUsername('newuser');
$client->user()->checkEmail('new@example.com');

短消息、好友、积分、标签

// 短消息:以系统管理员(uid=1)身份给用户发站内信、用户查列表
$client->pm()->sendFromSystem($toUid, '标题', '内容');   // 自动以 uid=1 发送
$list = $client->pm()->getList($uid, 1, 20, 'inbox');   // 收件箱,count + data
$client->pm()->checkNewPm($uid, $more);
$client->pm()->send($fromUid, $toUsername, $subject, $message);
$client->pm()->call('ls', [...]);   // 其它接口见 document/html/pm.htm

// 好友
$client->friend()->add($uid, $friendid, $comment);
$client->friend()->delete($uid, $friendid);
$client->friend()->call('ls', [...]);

// 积分
$client->credit()->request($uid, $from, $to, $toappid, $amount);

// 标签
$client->tag()->getTag($tagname, $nums);

短信发送(腾讯云)

本 SDK 提供腾讯云短信发送封装,需单独安装腾讯云短信库(仅短信,无需全产品 SDK):

composer require tencentcloud/sms
use UCenter\Sdk\Sms\TencentCloudSms;

$sms = new TencentCloudSms(
    'your_secret_id',      // 腾讯云 API 密钥 SecretId
    'your_secret_key',     // 腾讯云 API 密钥 SecretKey
    '1400006666',          // 短信 SdkAppId(控制台应用管理)
    '您的签名',             // 短信签名内容(国内必填)
    'ap-guangzhou'         // 地域,默认 ap-guangzhou
);

// 发送单条
$result = $sms->sendOne('13800138000', '1110', ['123456']);  // 模板 ID、模板参数
// $result['Code'] === 'Ok' 表示成功

// 批量发送
$results = $sms->send(['13800138000', '13900139000'], '1110', ['验证码']);

详见 docs/SDK使用文档.md 中「短信发送」章节。

微信模板消息

发送微信公众号模板消息(服务号 + 已审核模板):

use UCenter\Sdk\Wechat\WechatTemplateMessage;

$wechat = new WechatTemplateMessage(
    'account_1',       // 公众号 id(多公众号时用于区分)
    'wx_appid',       // 公众号 appid
    'app_secret_key'  // 公众号密钥 key / AppSecret
);

$res = $wechat->send(
    'user_openid',           // 接收者 openid
    'TEMPLATE_ID',           // 模板 id(公众平台已审核)
    [                        // 模板参数(键为模板占位符名)
        'first' => '您好,订单状态更新',
        'keyword1' => '202308150001',
        'keyword2' => '已发货',
        'remark' => '感谢使用',
    ],
    'https://example.com/order/123',  // 可选,点击跳转 URL
    []   // 可选,跳转小程序 ["appid"=>"","pagepath"=>""]
);
// $res['errcode'] === 0 表示成功,$res['msgid'] 为消息 id

详见 docs/SDK使用文档.md 中「微信模板消息」章节。

直接请求任意接口

$result = $client->request('user/get_user', ['username' => 'test', 'isuid' => 0]);

自定义 HTTP 客户端

若需使用 Guzzle 等,可注入自定义客户端:

$client->setHttpClient(function (string $url, array $headers, string $body): array {
    // 发送请求,返回 ['body' => string, 'http_code' => int]
});

测试

单元测试

composer install
./vendor/bin/phpunit

脚本真实调用(call_login.php)

scripts/call_login.php 支持多种运行模式,可对 UCenter 发起真实请求,便于自测:

  • login:登录(用户名+密码 或 类型+标识),可选 JWT 签发 access_token、本地绑定库
  • parse_token:解析 JWT,输出载荷
  • get_bindings / bind / unbind:绑定关系查询/绑定/解绑
  • update_profile:设置昵称、头像、手机号、邮箱

配置方式:编辑脚本顶部「配置区」或使用环境变量(如 UC_RUN_MODEUC_BASE_URLUC_APP_IDUC_SECRET 等)。详见 scripts/README.md

php scripts/call_login.php

Demo(若存在 demo 目录)

若项目包含 demo/demo.php,可复制 demo/config.example.phpdemo/config.php 并填写 base_url、app_id、secret 后执行 php demo/demo.php 测试各模块接口。

文档与错误码

  • 全局参数、签名、Token:document/html/base.htm
  • 用户:document/html/user.htm
  • 短消息:document/html/pm.htm
  • 好友:document/html/friend.htm
  • 积分:document/html/credit.htm
  • 标签:document/html/tag.htm

接口返回错误时 SDK 会抛出 UCenter\Sdk\Exception\UCenterException,可通过 getResponse() 获取原始返回。

软件架构

src/
├── UCenterClient.php      # 客户端:签名、Token、HTTP 请求,可选 JwtToken / BindingStore
├── Api/
│   ├── BaseApi.php
│   ├── UserApi.php        # 用户注册/登录/获取/编辑/绑定/解绑/同步登录等
│   ├── PmApi.php          # 短消息
│   ├── FriendApi.php      # 好友
│   ├── CreditApi.php      # 积分
│   └── TagApi.php         # 标签
├── Backend/               # 直连数据库时用
│   ├── BackendInterface.php
│   └── DatabaseBackend.php
├── Binding/               # 混合模式:绑定关系存本地
│   ├── BindingStoreInterface.php
│   └── DatabaseBindingStore.php
├── Jwt/
│   └── JwtToken.php       # JWT 签发与验证,登录成功可返回 access_token
├── Exception/
│   └── UCenterException.php
└── Sms/、Wechat/          # 短信、微信模板消息等

参与贡献

  1. Fork 本仓库
  2. 新建 Feat_xxx 分支
  3. 提交代码
  4. 新建 Pull Request