本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:WWW/待办事宜/update3-改动diff.txt。
update3-改动diff
=======================================================================
app/init.php
=======================================================================
--- flinthub1.0.0/app/init.php 2026-09-09 21:35:00.171689800 +0800
+++ app/init.php 2026-09-15 11:32:59.820790600 +0800
@@ -38,72 +38,13 @@
$tableCheck = true;
if ($tableCheck) {
// ★ Session 使用独立 PDO 连接,与业务连接物理隔离,避免 2014 游标冲突
- session_set_save_handler(
- // open
- function () { return true; },
- // close
- function () { return true; },
- // read
- function ($id) {
- try {
- $conn = \app\Core\Database::getSessionConnection();
- // [SplitDB] SQLite:expires 存秒级时间戳,与 PHP time() 比较
- $stmt = $conn->prepare("SELECT data FROM sessions WHERE id = :id AND expires > :now");
- $stmt->execute([':id' => $id, ':now' => time()]);
- $r = $stmt->fetch(\PDO::FETCH_ASSOC);
- $stmt->closeCursor();
- return $r ? $r['data'] : '';
- } catch (\Throwable $e) {
- return '';
- }
- },
- // write
- function ($id, $data) {
- try {
- $conn = \app\Core\Database::getSessionConnection();
- // [SplitDB] SQLite UPSERT(ON CONFLICT 兼容 3.33);expires = time() + 1800(30 分钟)
- $stmt = $conn->prepare(
- "INSERT INTO sessions (id, data, expires) VALUES (:id, :data, :expires)
- ON CONFLICT(id) DO UPDATE SET data = :data2, expires = :expires2"
- );
- $stmt->execute([
- ':id' => $id, ':data' => $data, ':expires' => time() + 1800,
- ':data2' => $data, ':expires2' => time() + 1800,
- ]);
- $stmt->closeCursor();
- return true;
- } catch (\Throwable $e) {
- \error_log('Session write error: ' . $e->getMessage());
- return false;
- }
- },
- // destroy
- function ($id) {
- try {
- $conn = \app\Core\Database::getSessionConnection();
- $stmt = $conn->prepare("DELETE FROM sessions WHERE id = :id");
- $stmt->execute([':id' => $id]);
- $stmt->closeCursor();
- return true;
- } catch (\Throwable $e) {
- return false;
- }
- },
- // gc
- function ($maxLifetime) {
- try {
- $conn = \app\Core\Database::getSessionConnection();
- // [SplitDB] SQLite:expires 秒级时间戳与 PHP time() 比较
- $stmt = $conn->prepare("DELETE FROM sessions WHERE expires < :now");
- $stmt->execute([':now' => time()]);
- $count = $stmt->rowCount();
- $stmt->closeCursor();
- return $count;
- } catch (\Throwable $e) {
- return 0;
- }
- }
- );
+ // ★ PHP 8.4+:必须传「实现 SessionHandlerInterface 的对象」。
+ // 原「独立回调」写法自 8.4 起已弃用,会输出:
+ // Deprecated: session_set_save_handler(): Providing individual callbacks instead of
+ // an object implementing SessionHandlerInterface is deprecated
+ // 处理器逻辑整体迁至 app/Core/SessionHandler.php,6 个方法逐一对应原闭包,
+ // 且刻意不实现 validateId/updateTimestamp,行为与原实现完全一致。
+ session_set_save_handler(new \app\Core\SessionHandler());
}
} catch (\Throwable $e) {
// DB 不可用时回退到文件 Session,无需处理
=======================================================================
app/SplitDB/ViewCounter.php
=======================================================================
--- flinthub1.0.0/app/SplitDB/ViewCounter.php 2026-09-02 14:10:56.965203400 +0800
+++ app/SplitDB/ViewCounter.php 2026-09-15 11:56:07.042168600 +0800
@@ -27,7 +27,7 @@
- @param int $topicId 主题 ID
- @param PDO|null $mainDb main_index 连接(降级直写用;null 时自动取)
*/
- public static function inc(int $topicId, PDO $mainDb = null): void
+ public static function inc(int $topicId, ?PDO $mainDb = null): void
{
// 有 APCu → 内存计数,flush 时批量落库(inc 时传 TTL:新键创建即设过期时间,
// 避免只增不减的键永驻 APCu 共享内存;已存在的键继续累加)
@@ -54,7 +54,7 @@
- @param PDO|null $mainDb main_index 连接
- @return int 落库的主题数
*/
- public static function flush(PDO $mainDb = null): int
+ public static function flush(?PDO $mainDb = null): int
{
if (!function_exists('apcu_fetch') || !class_exists('APCUIterator')) {
return 0; // 无 APCu 环境无需 flush
=======================================================================
app/Helpers/CoverTemplate.php
=======================================================================
--- flinthub1.0.0/app/Helpers/CoverTemplate.php 2026-08-25 15:43:17.071008400 +0800
+++ app/Helpers/CoverTemplate.php 2026-09-15 11:56:54.237970900 +0800
@@ -152,6 +152,14 @@
/** 字符宽度估算:ASCII 0.5 单位(宽字符 0.9),其余(中文/全角)1 单位 */
private static function charUnits(string $ch): float
{
+ // ★ PHP 8.5:ord() 传入非单字节字符串已弃用
+ // (Deprecated: ord(): Providing a string that is not one byte long is deprecated)。
+ // 本函数入参来自 preg_split('//u', ...),即「UTF-8 字符」——中文/全角为 2~4 字节,
+ // 直接 ord() 会按字符数刷屏告警。多字节字符原本就走下面 return 1.0 分支,
+ // 故提前返回,语义与改前完全一致、零行为变更。
+ if (\strlen($ch) > 1) {
+ return 1.0;
+ }
$o = \ord($ch);
if ($o < 0x80) {
return (\preg_match('/[MWmw@#%&]/', $ch) ? 0.9 : 0.5);
=======================================================================
app/Controllers/ApiController.php
=======================================================================
--- flinthub1.0.0/app/Controllers/ApiController.php 2026-09-10 12:37:17.637584100 +0800
+++ app/Controllers/ApiController.php 2026-09-15 11:57:46.878081900 +0800
@@ -368,7 +368,8 @@
$data = \curl_exec($ch);
$httpCode = (int)\curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$location = (string)\curl_getinfo($ch, CURLINFO_REDIRECT_URL);
- \curl_close($ch);
+ // ★ PHP 8.5:curl_close() 已弃用(CurlHandle 对象自 PHP 8.0 起自动释放,
+ // 该调用自 8.0 起即无实际作用),故删除。句柄随 $ch 重赋值/作用域结束释放。
if ($data === false) return false;
if ($httpCode >= 300 && $httpCode < 400 && $location !== '') {
@@ -497,7 +498,8 @@
}
imagepng($img);
- imagedestroy($img);
+ // ★ PHP 8.5:imagedestroy() 已弃用(GdImage 对象自动释放),故删除。
+ // 其后紧跟 exit,对象必然被回收,行为不变。
exit;
}
=======================================================================
app/Helpers/Plugin.php
=======================================================================
--- flinthub1.0.0/app/Helpers/Plugin.php 2026-09-14 13:00:39.750873100 +0800
+++ app/Helpers/Plugin.php 2026-09-15 11:58:04.781580100 +0800
@@ -198,7 +198,8 @@
}
$response = curl_exec($ch);
$curlErr = curl_error($ch);
- curl_close($ch);
+ // ★ PHP 8.5:curl_close() 已弃用(CurlHandle 对象自 PHP 8.0 起自动释放),故删除。
+ // curl_error() 已在上一行取完,删除不影响错误处理。
if ($response === false) {
return ['ok' => false, 'body' => '', 'error' => 'curl: ' . $curlErr];
}
=======================================================================
app/Helpers/Upload.php
=======================================================================
--- flinthub1.0.0/app/Helpers/Upload.php 2026-09-06 11:46:11.971856900 +0800
+++ app/Helpers/Upload.php 2026-09-15 11:58:35.753458900 +0800
@@ -55,7 +55,8 @@
$finfo = \finfo_open(FILEINFO_MIME_TYPE);
if ($finfo) {
$mime = \finfo_file($finfo, $file['tmp_name']);
- \finfo_close($finfo);
+ // ★ PHP 8.5:finfo_close() 已弃用(finfo 对象自动释放),故删除。
+ // $mime 已在上一行取完,删除不影响后续判断。
if ($mime === false) return ['success' => false, 'error' => '无法识别文件类型'];
$allowedMimes = [
@@ -217,7 +218,8 @@
$newH = (int)round($srcH * $ratio);
$thumb = \imagecreatetruecolor($newW, $newH);
- if ($thumb === false) { \imagedestroy($src); return; }
+ // ★ PHP 8.5:imagedestroy() 已弃用(GdImage 自动释放),故删除调用,保留 return;
+ if ($thumb === false) { return; }
// 保持 PNG 透明
if ($ext === 'png') {
@@ -226,7 +228,7 @@
}
\imagecopyresampled($thumb, $src, 0, 0, 0, 0, $newW, $newH, $srcW, $srcH);
- \imagedestroy($src);
+ // ★ PHP 8.5:imagedestroy($src) 已弃用(GdImage 自动释放),故删除。
if ($ext === 'jpg' || $ext === 'jpeg') {
$outputFn($thumb, $thumbPath, 80);
@@ -237,7 +239,7 @@
} else {
$outputFn($thumb, $thumbPath);
}
- \imagedestroy($thumb);
+ // ★ PHP 8.5:imagedestroy($thumb) 已弃用(GdImage 自动释放),故删除。
@\chmod($thumbPath, 0644);
} catch (\Throwable $e) {
\error_log('[Upload] GD thumbnail failed: ' . $e->getMessage());