Files
superlink/api/common/Api.php
T

86 lines
3.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 统一接口基座 v1(批次1「架构筑基」REV-ARCH-2)
*
* 所有业务接口统一走 Api::boot(),收敛「require 一串公共文件 + checkAjax +
* checkPermission + DB 连接」的重复样板,并提供统一的异常→JSON 兜底。
*
* 用法(endpoint 顶部):
* require_once __DIR__ . '/../common/Api.php';
* $pdo = Api::boot(['module' => 'preliminary']); // 登录 + 模块权限(写接口另含 Ajax/CSRF)
* $pdo = Api::boot(); // 仅要求登录(如 session.php)
* $pdo = Api::boot(['super' => true]); // 仅超级管理员
* $pdo = Api::boot(['permissions' => [...]]); // 任一权限
* $pdo = Api::boot(['public' => true]); // 免登录(仅 login/forgot/csrf)
*
* boot() 统一执行:
* - 安全 Session(httponly/samesite)
* - POST/PUT/PATCH/DELETE:checkAjax(X-Requested-With)+ checkCsrf(Token 头)
* - 登录态 + 权限
* - 返回 PDO(后续代码可直接用 $pdo;原 `$pdo = DB::getInstance()->getPdo();`
* 属冗余无害,可保留)
*
* 本文件另注册全局异常处理器:未捕获异常统一转 JSON 500 + 技术日志。
*/
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/response.php';
require_once __DIR__ . '/logger.php';
require_once __DIR__ . '/security.php';
require_once __DIR__ . '/auth.php';
require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/validate.php';
require_once __DIR__ . '/duplicate_check.php';
require_once __DIR__ . '/completeness.php';
/** 统一异常处理:未捕获异常 → JSON 500 + 技术日志(REV-ARCH-3) */
set_exception_handler(function (\Throwable $e) {
logError('未捕获异常', [
'msg' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'uri' => $_SERVER['REQUEST_URI'] ?? '',
]);
if (!headers_sent()) {
http_response_code(500);
header('Content-Type: application/json; charset=utf-8');
}
echo json_encode(['code' => 500, 'msg' => '服务器内部错误,请稍后重试'], JSON_UNESCAPED_UNICODE);
exit;
});
class Api
{
/**
* 统一引导
* @param array $opts 见文件头注释
* @return PDO
*/
public static function boot(array $opts = [])
{
startSessionSecure();
$isWrite = in_array($_SERVER['REQUEST_METHOD'] ?? 'GET', ['POST', 'PUT', 'PATCH', 'DELETE'], true);
if ($isWrite) {
checkAjax();
}
if (empty($opts['public'])) {
if (!empty($opts['super'])) {
requireSuperAdmin();
} elseif (!empty($opts['module'])) {
checkPermission($opts['module']);
} elseif (!empty($opts['permissions'])) {
checkAnyPermission($opts['permissions']);
} else {
requireLogin();
}
}
if ($isWrite) {
checkCsrf();
}
return DB::getInstance()->getPdo();
}
}