一、ReturnInfoPubid函数
function ReturnInfoPubid($classid, $id, $tid = 0)它的作用是把 栏目ID(classid) + 系统模型ID(tid) + 信息ID(id) 拼接成一个唯一的发布标识 pubid,格式为:
1 + (tid补零到5位) + (id补零到10位)
举个例子:
- tid = 1 → ReturnAllInt(1, 5) → "00001"
- id = 123 → ReturnAllInt(123, 10) → "0000000123"
- classid = 5 不参与拼接到 pubid 中(仅用于查找 tid)
- 结果:"1" . "00001" . "0000000123" → "1000010000000123"
用途: 帝国CMS里每个信息有一个全局唯一的 pubid,用于跨表引用(比如评论、附件、关键词关联等),不管信息在哪个系统模型或栏目,都能通过这个 ID 定位到。
如果觉得不好理解,直接查看下文第四点
文件位置: e/class/connect.php
function ReturnInfoPubid($classid, $id, $tid = 0) {
global $class_r;
$classid = (int)$classid;
$id = (int)$id;
if (empty($tid)) {
$tid = $class_r[$classid]['tid'];
}
$tid = (int)$tid;
$pubid = '1' . ReturnAllInt($tid, 5) . ReturnAllInt($id, 10);
return $pubid;
}
辅助函数 ReturnAllInt
function ReturnAllInt($val, $num) {
// 将 $val 左侧补零到 $num 位
// 例:ReturnAllInt(5, 5) → "00005"
// 例:ReturnAllInt(123, 10) → "0000000123"
}
二、pubid 的编码格式
pubid = "1" + tid(5位零补) + id(10位零补)
| 段 | 长度 | 说明 | 示例 |
|---|---|---|---|
| 前缀 | 1 | 固定为 "1" |
1 |
| tid | 5 | 系统模型ID,左侧补零 | 00001 |
| id | 10 | 信息ID,左侧补零 | 0000000123 |
完整示例:
1 00001 0000000123
→ "1000010000000123"
分解:
- 前缀:
1 - tid:
00001(模型ID = 1,新闻模型) - id:
0000000123(信息ID = 123)
长度总计 16 位字符。
三、为什么要 pubid?
3.1 帝国CMS 的多表结构
帝国CMS 允许不同栏目使用不同的系统模型,每个模型对应一张独立的数据表。
| 栏目 | 系统模型(tid) | 存储表 |
|---|---|---|
| 新闻中心 | 1 | phome_ecms_news |
| 产品中心 | 2 | phome_ecms_product |
| 下载中心 | 3 | phome_ecms_download |
3.2 问题:id 不唯一
假设:
- 新闻栏目第 5 篇文章 →
phome_ecms_news表中id = 5 - 产品栏目第 5 个产品 →
phome_ecms_product表中id = 5
两个 id = 5 含义完全不同,单看 id 无法区分是哪张表的数据。
3.3 解决方案:pubid
pubid 将 tid(表标识)和 id(行标识)编码成一个全局唯一的字符串:
| 数据 | tid | id | pubid |
|---|---|---|---|
| 新闻 #5 | 1 | 5 | 1000010000000005 |
| 产品 #5 | 2 | 5 | 1000020000000005 |
虽然 id 都是 5,但 pubid 不同——tid 编码在前 5 位,一眼就能区分。
四、pubid 的典型应用场景
4.1 评论系统
评论表 enewspl_* 用 pubid 标记每条评论属于哪篇文章:
// 获取某篇文章的评论
$pubid = ReturnInfoPubid($classid, $id);
$plnum = $empire->gettotal(
"SELECT COUNT(*) AS total FROM {$dbtbpre}enewspl_{$restb}
WHERE pubid='$pubid'"
);
无论文章在哪个表,用 pubid 定位即可,不需要知道文章是新闻还是产品。
4.2 附件/文件关联
上传的附件通过 pubid 关联到信息:
// 插入文件记录
$pubid = ReturnInfoPubid($classid, $id);
$empire->query(
"INSERT INTO {$dbtbpre}enewsfile_{$fstb}
(pubid, filename, filesize, adduser, path, filetime, ...)
VALUES ('$pubid', '$filename', '$filesize', '$adduser', ...)"
);
4.3 投票关联
$pubid = ReturnInfoPubid($r['classid'], $r['id']);
$infopr = $empire->fetch1(
"SELECT diyotherlink FROM {$dbtbpre}enewsinfovote
WHERE pubid='$pubid'"
);
4.4 副栏目/副表数据
$pubid = ReturnInfoPubid($classid, $id);
$infor = $empire->fetch1(
"SELECT * FROM {$dbtbpre}enewsfz_info
WHERE pubid='$pubid'"
);
五、常见误解
❌ 误解:pubid 是用来"反解"出 tid 和 id 的
pubid 的格式(1 + tid(5位) + id(10位))理论上可以反解:
$tid = (int)substr($pubid, 1, 5); // 取第 2-6 位
$id = (int)substr($pubid, 6, 10); // 取第 7-16 位
但帝国CMS 没有任何函数或代码这样做。
✓ 实际用法
需要用 tid 时,代码里已经通过 classid 查到了:
$tid = $class_r[$classid]['tid'];
$pubid = ReturnInfoPubid($classid, $id); // 生成 pubid
pubid 只用于数据库查询——作为 WHERE 条件的键,不做反解。
六、pubid 的数据流图解
七、总结
| 问题 | 答案 |
|---|---|
| 哪个文件 | e/class/connect.php |
| 做什么 | 生成全局唯一的信息标识 pubid |
| 格式 | 1 + tid(5位零补) + id(10位零补) |
| 长度 | 固定 16 位 |
| 为什么需要 | 跨表唯一标识一条信息(不同模型有各自的 id 序列) |
| 怎么用 | 存入库表,用于 WHERE 查询 |
| 能反解吗 | 技术上可以,但帝国CMS没有这样做 |
| 如何获取 tid | 从 $class_r[$classid]['tid'] 获取,而非从 pubid 反解 |


