# runkit7扩展安装教程

## 说明

本主题已内置授权绕过代码，但需要服务器安装 **runkit7** PHP扩展才能生效。

runkit7扩展用于在运行时重定义PHP函数，本主题利用它绕过授权验证，不修改主题任何功能代码。

---

## 安装步骤（宝塔面板 / CentOS / Ubuntu通用）

### 第一步：安装编译依赖

```bash
# CentOS
yum install -y gcc gcc-c++ make autoconf

# Ubuntu/Debian
apt-get install -y gcc g++ make autoconf
```

### 第二步：下载runkit7源码

```bash
cd /tmp
git clone https://github.com/runkit7/runkit7.git
cd runkit7
```

### 第三步：编译安装

```bash
# 注意：把下面的PHP路径换成你实际的PHP版本路径
# 宝塔PHP 8.2路径示例：/www/server/php/82/bin/phpize

/www/server/php/82/bin/phpize
./configure --with-php-config=/www/server/php/82/bin/php-config
make -j4
make install
```

> 其他PHP版本路径参考：
> - PHP 7.4: /www/server/php/74/
> - PHP 8.0: /www/server/php/80/
> - PHP 8.1: /www/server/php/81/
> - PHP 8.2: /www/server/php/82/

### 第四步：配置php.ini

```bash
# 编辑php.ini（宝塔路径示例）
vi /www/server/php/82/etc/php.ini

# 在文件末尾添加一行：
extension=runkit7.so
```

或者用命令一键添加：
```bash
echo "extension=runkit7.so" >> /www/server/php/82/etc/php.ini
```

### 第五步：重启PHP

```bash
# 宝塔面板
killall php-fpm
/www/server/php/82/sbin/php-fpm -D

# 或者在宝塔面板 → 软件商店 → PHP-8.2 → 重启
```

---

## 验证安装

```bash
# 查看已加载的扩展，看是否有runkit7
php -m | grep runkit

# 验证函数是否可用
php -r "echo function_exists('runkit_function_redefine') ? 'runkit7安装成功' : '安装失败';"
```

如果输出 `runkit7安装成功`，说明扩展已正常工作。

---

## 常见问题

### Q1: 提示 `phpize: command not found`
A: 没有安装php-dev，宝塔面板默认已安装。如果是自定义编译的PHP，请确保phpize在PHP的bin目录下。

### Q2: 编译报错 `configure: error: Cannot find php-config`
A: 检查`--with-php-config`路径是否正确，确保php-config文件存在。

### Q3: 安装后php -m看不到runkit7
A: 
1. 确认php.ini路径正确：`php -i | grep "Loaded Configuration File"`
2. 确认extension=runkit7.so已添加到正确的php.ini
3. 确认扩展文件存在：`ls /www/server/php/82/lib/php/extensions/no-debug-non-zts-*/runkit7.so`
4. 重启PHP-FPM

### Q4: 宝塔面板怎么操作？
A: 
1. 宝塔面板 → 软件商店 → 对应PHP版本 → 设置 → 安装扩展
2. 如果列表里没有runkit7，就用上面的命令行方式安装
3. 安装完在"配置修改"里加 `extension=runkit7.so`，保存后重启PHP

---

## 授权绕过原理

本主题在 `functions.php` 文件末尾添加了以下代码（不修改主题任何原有功能）：

```php
if (function_exists('runkit_function_redefine')) {
    @runkit_function_redefine('joe_check_auth', '', 'return true;');
    @runkit_function_redefine('joe_is_auth', '', 'return true;');
    @runkit_function_redefine('joe_exception', '', 'return true;');
    @runkit_function_redefine('joe_get_auth', '', 'return ["status"=>true,"domain"=>$_SERVER["HTTP_HOST"] ?? "","time"=>time()];');
}
```

只有当runkit7扩展已安装时，这段代码才会生效；未安装时主题正常运行（但会显示授权提示）。

---

## 技术支持

如遇安装问题，请检查：
1. PHP版本是否 ≥ 7.4
2. 编译依赖是否安装完整
3. php.ini路径是否正确
4. PHP-FPM是否重启

---

# 数据库表修复（安装主题后必看）

## 问题说明

Joe主题需要3张自定义表（订单表、友情链接表、拓展数据表），以及在文章表和评论表里添加额外字段。如果主题启用时没有自动创建，会出现以下错误：

- `Table 'xxx.typecho_friends' doesn't exist`
- `Unknown column 'agree' in 'field list'`
- `Unknown column 'views' in 'field list'`

出现以上错误时，执行下面的SQL修复脚本即可。

---

## 修复方法一：phpMyAdmin（推荐）

1. 登录宝塔面板 → 数据库 → 找到你的数据库 → 点"管理"
2. 左侧点你的数据库名
3. 顶部点"SQL"标签
4. 把下面的SQL全部复制粘贴进去
5. 点"执行"
6. 看到"执行成功"就完成了

## 修复方法二：SSH命令行

1. SSH登录服务器
2. 执行：`mysql -u 用户名 -p'密码' 数据库名`
3. 把SQL粘贴进去，回车执行
4. 输入`exit;`退出

## 修复方法三：一行命令

把SQL保存为`fix.sql`文件，然后执行：
```bash
mysql -u 用户名 -p'密码' 数据库名 < fix.sql
```

---

## SQL修复脚本（复制全部执行）

> 注意：表前缀默认是`typecho_`，如果你的不是，请把所有`typecho_`替换成你的前缀。

```sql
-- ========== Joe主题数据库修复脚本 ==========

-- 1. 创建订单表
CREATE TABLE IF NOT EXISTS `typecho_orders` (
  `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `trade_no` VARCHAR(64) NOT NULL UNIQUE COMMENT '系统订单号',
  `api_trade_no` VARCHAR(64) DEFAULT NULL COMMENT '第三方平台订单号',
  `name` VARCHAR(255) NOT NULL COMMENT '商品/订单名称',
  `parent_id` VARCHAR(255) NOT NULL COMMENT '本体ID',
  `parent_title` VARCHAR(255) DEFAULT NULL COMMENT '本体标题',
  `type` VARCHAR(32) NOT NULL COMMENT '订单类型',
  `channel` VARCHAR(32) NOT NULL COMMENT '订单通道',
  `price` DECIMAL(10,2) NOT NULL COMMENT '订单价格',
  `ip` VARCHAR(128) DEFAULT NULL COMMENT '下单IP',
  `user_id` INT NOT NULL COMMENT '用户ID',
  `created` INT NOT NULL DEFAULT '0' COMMENT '创建时间戳',
  `modified` INT NOT NULL DEFAULT '0' COMMENT '修改时间戳',
  `timeout` INT NOT NULL DEFAULT '1800' COMMENT '订单超时时间(秒)',
  `amount` DECIMAL(10,2) DEFAULT NULL COMMENT '实际支付金额',
  `result` TEXT DEFAULT NULL COMMENT '订单数据',
  `status` BOOLEAN NOT NULL DEFAULT FALSE COMMENT '订单状态 0=未支付 1=已支付',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单主表';

-- 2. 创建友情链接表
CREATE TABLE IF NOT EXISTS `typecho_friends` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `title` VARCHAR(255) NOT NULL,
  `url` VARCHAR(255) NOT NULL,
  `description` TEXT DEFAULT NULL,
  `logo` TEXT DEFAULT NULL,
  `rel` VARCHAR(255) DEFAULT NULL,
  `position` VARCHAR(255) DEFAULT NULL,
  `email` VARCHAR(64) DEFAULT NULL,
  `order` INT NOT NULL DEFAULT 0,
  `status` BOOLEAN NOT NULL DEFAULT FALSE,
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='友情链接';

-- 3. 创建拓展数据表
CREATE TABLE IF NOT EXISTS `typecho_extras` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `table` VARCHAR(32) NOT NULL,
  `name` VARCHAR(150) NOT NULL,
  `parent` INT NOT NULL,
  `value` TEXT DEFAULT NULL,
  `json` BOOLEAN NOT NULL DEFAULT FALSE,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_table_name_parent` (`table`, `name`, `parent`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='拓展数据';

-- 4. 给文章表添加浏览量字段（已存在会报错，忽略即可）
ALTER TABLE `typecho_contents` ADD `views` INT NOT NULL DEFAULT 0;

-- 5. 给文章表添加点赞字段
ALTER TABLE `typecho_contents` ADD `agree` INT NOT NULL DEFAULT 0;

-- 6. 给评论表添加点赞字段
ALTER TABLE `typecho_comments` ADD `agree` INT NOT NULL DEFAULT 0;

-- ========== 修复完成 ==========
```

---

## 常见问题

### Q: 执行时报"表已存在"或"字段已存在"怎么办？
A: 正常现象，说明之前已经创建过了，忽略即可。`IF NOT EXISTS`会自动跳过已存在的表。

### Q: 怎么查看我的表前缀？
A: 打开Typecho的`config.inc.php`文件，找到`$db = new \Typecho\Db('Pdo_Mysql', 'typecho_');`，第二个参数就是表前缀。

### Q: 执行完SQL还是报错？
A: 
1. 确认表前缀是否正确
2. 确认SQL是在正确的数据库里执行的
3. 清除浏览器缓存，刷新页面
4. 重启PHP-FPM

---

## 验证修复是否成功

执行完SQL后，访问网站首页，如果不再出现数据库错误，说明修复成功。

也可以在数据库里执行`SHOW TABLES;`，确认有以下表：
- typecho_orders
- typecho_friends
- typecho_extras

并且`typecho_contents`表里有`views`和`agree`字段。
