sqlite-web 0.7.2
gitea.db
issue
Create
Query
access
access_token
action
action_artifact
action_run
action_run_index
action_run_job
action_runner
action_runner_token
action_schedule
action_schedule_spec
action_task
action_task_output
action_task_step
action_tasks_version
action_variable
app_state
attachment
auth_token
badge
branch
collaboration
comment
commit_status
commit_status_index
commit_status_summary
commit_sync_log
commit_sync_status
dbfs_data
dbfs_meta
deploy_key
email_address
email_hash
external_login_user
follow
gpg_key
gpg_key_import
hook_task
issue
issue_assignees
issue_content_history
issue_dependency
issue_index
issue_label
issue_pin
issue_user
issue_watch
label
language_stat
lfs_lock
lfs_meta_object
login_source
milestone
mirror
notice
notification
oauth2_application
oauth2_authorization_code
oauth2_grant
org_user
package
package_blob
package_blob_upload
package_cleanup_rule
package_file
package_property
package_version
project
project_board
project_issue
protected_branch
protected_tag
public_key
pull_auto_merge
pull_request
push_mirror
reaction
release
renamed_branch
repo_archiver
repo_hidden_file
repo_indexer_status
repo_license
repo_redirect
repo_topic
repo_transfer
repo_unit
repository
review
review_state
secret
session
sqlite_sequence
star
stopwatch
system_setting
task
team
team_invite
team_repo
team_unit
team_user
topic
tracked_time
two_factor
upload
user
user_badge
user_blocking
user_open_id
user_redirect
user_setting
version
watch
webauthn_credential
webhook
Toggle helper tables
Structure
Content
Query
Insert
Drop
Import
Export
Update row 178 in issue
id
Primary key.
INTEGER NOT NULL
repo_id
INTEGER
index
INTEGER
poster_id
INTEGER
original_author
TEXT
original_author_id
INTEGER
name
🔍 代码审查报告:pay-260519 - 1
TEXT
content
## 自动代码审查报告 **分支**: pay-260519 **提交**: `4de14a2cff5bc6855ae3992c46f2b1b3e911c7bc` **提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com) **时间**: 2026-05-19 13:21:45 --- ## 1. 审查摘要 - **代码质量评分**:5.5 / 10 分 - **总体评价**:代码整体实现了门店查询、缓存、距离排序及多端适配等核心业务,但存在明显的**安全漏洞**(SQL注入)、**线上阻断风险**(遗留调试代码)及**性能瓶颈**(N+1查询、PHP层全量排序)。代码结构高度耦合,重复逻辑较多,未充分利用框架的查询构造器与缓存机制,可维护性与扩展性有待提升。 - **风险等级**:🔴 高 ## 2. 问题详情 | 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) | | :--- | :--- | :--- | :--- | :--- | | 🔴 严重 | `get_shop_list_order_by_distance` (~L560) | **SQL 注入漏洞**:`$shop_name` 未经过滤直接拼接到 SQL 字符串中,攻击者可构造恶意输入破坏查询或窃取数据。 | 使用框架查询构造器或参数绑定,禁止字符串拼接。 | `$this->db->like('_name', $shop_name, 'both');` | | 🔴 严重 | `get_shop_list_order_by_distance` (~L585) | **线上阻断风险**:遗留 `echo $this->db->last_query(); exit;`,一旦部署将直接中断所有请求。 | 立即删除该行,调试信息应通过日志记录而非直接输出并终止。 | 删除 `echo...exit;` 代码块 | | 🔴 严重 | 文件顶部 (~L4) | **全局状态污染**:在类外部执行 `$CI = &get_instance();` 并加载模型,违反框架生命周期,易导致依赖冲突或内存泄漏。 | 移除文件顶部代码,依赖加载统一移至 `__construct()` 中。 | 删除顶部 `$CI = &get_instance();` 相关代码 | | 🟠 警告 | `get_community_shop_list` 等多处 | **N+1 查询性能瓶颈**:在 `foreach` 循环中逐行调用 `get_miniprogram_consumption_methods()`,门店数量多时将产生海量数据库请求。 | 收集所有 `shop_id` 后使用 `where_in` 批量查询,或在主 SQL 中 `JOIN` 关联配置表一次性获取。 | `$ids = array_column($shop_data, 'shop_id'); $configs = $this->config_model->get_batch($ids);` | | 🟠 警告 | `get_id_by_distance` (~L230) | **内存与计算瓶颈**:全量拉取门店数据后在 PHP 中循环计算距离并排序,数据量稍大即触发 OOM 或超时。 | 将距离计算下推至数据库层(MySQL 空间函数或 `ORDER BY` 近似公式),或使用 Redis GEO。 | `ORDER BY (latitude - ?)^2 + (longitude - ?)^2 ASC` | | 🟠 警告 | `get_community_shop_list` (~L430) | **迭代安全隐患**:在 `foreach` 中直接使用 `unset($shop_data[$k])` 过滤数据,可能导致数组键断裂或后续逻辑索引错乱。 | 使用 `array_filter` 进行安全过滤,或先收集需剔除的 ID 再统一处理。 | `$shop_data = array_values(array_filter($shop_data, fn($v) => !empty($v['book_operational_scene'])));` | | 🟡 建议 | 全文多处 | **违反 DRY 原则**:坐标转换、地址拼接、运营场景解析、营业时间格式化等逻辑在 5+ 个方法中重复编写。 | 抽取为私有辅助方法(如 `private function formatShopDisplayData(array $shop, string $from)`)。 | 统一封装处理逻辑,主方法仅负责查询与调用格式化。 | | 🟡 建议 | 全文多处 | **硬编码魔法值**:`$special_city_id = [2, 3, 4, 5, 34, 35]` 在多处重复出现,后期维护极易遗漏。 | 提取为类常量或独立配置文件。 | `const SPECIAL_CITY_IDS = [2, 3, 4, 5, 34, 35];` | | 🟡 建议 | `get_cache_shop_data` (~L60) | **缓存序列化风险**:`json_encode($shop_data)` 未处理非 UTF-8 字符或资源类型,且 `set` + `expireAt` 为两次网络请求。 | 使用 `JSON_UNESCAPED_UNICODE`,或改用框架缓存驱动/Redis `SETEX` 原子操作。 | `$redis->setex($redis_key, 86400, json_encode($shop_data, JSON_UNESCAPED_UNICODE));` | | 🟡 建议 | `get_shop_list_order_by_distance` (~L555) | **类型安全缺失**:`$satisfy_shop_ids` 直接 `implode` 拼接,若包含非数字字符串将导致 SQL 语法错误。 | 强制类型转换或过滤,确保仅传入合法 ID。 | `$safe_ids = array_map('intval', array_filter($satisfy_shop_ids, 'is_numeric'));` | ## 3. 总结与行动建议 ### 🔑 优先修复的关键问题(P0/P1) 1. **立即移除调试代码**:删除 `get_shop_list_order_by_distance` 中的 `echo ... exit;`,避免线上服务雪崩。 2. **修复 SQL 注入**:将 `get_shop_list_order_by_distance` 中的原生 SQL 拼接全面替换为 CI 查询构造器(Query Builder)或预处理语句,特别是 `LIKE` 和 `IN` 条件。 3. **解决 N+1 查询**:对 `get_community_shop_list`、`get_shop_list_order_by_distance` 等列表接口,将循环内的单条查询改为批量查询(`where_in`)或 SQL `JOIN`,预计可降低 70%+ 数据库负载。 ### 🛠 后续重构与优化方向 1. **逻辑下沉与 DRY 重构**: - 创建 `private function processShopForDisplay(array $shopData, string $source = 'web')`,统一处理:坐标转换、距离计算、地址拼接、运营场景映射、营业时间格式化。 - 将重复的 `$this->load->model()` 移至类顶部或构造函数,避免运行时重复加载。 2. **距离排序架构升级**: - 若门店数据量 > 1000,强烈建议废弃 PHP 层 `get_distance()` 循环。改用 MySQL `ST_Distance_Sphere` 或 Redis `GEODIST` 实现数据库/缓存层排序,性能可提升 10 倍以上。 3. **框架规范适配**: - 注:当前代码结构高度符合 **CodeIgniter 3** 规范。若 `phpci` 为内部定制框架,请确认其是否兼容 CI3 的 `DB_driver` 与 `load` 机制。建议统一使用框架提供的缓存组件(如 `$this->cache->redis->get()`)替代原生 `get_aliyun_redis_conn()`,以便统一连接池管理与异常捕获。 - 为所有公开方法添加 PHPDoc `@return` 类型声明,并逐步引入 PHP 7.4+ 类型提示(如 `public function get_info(array $param): array`)。 4. **安全与健壮性加固**: - 对 `$param` 输入增加统一过滤层(如 `filter_var` 或框架验证器),避免依赖零散的 `intval()`/`trim()`。 - 敏感操作(如 `add_shop_after`)建议加入数据库事务包裹,确保多表插入的原子性。 > 💡 **局限性说明**:由于未提供 `Simple_model` 基类、全局辅助函数(`locationTurnTxMap`, `get_distance`, `throwError` 等)及数据库表结构,部分业务逻辑的边界条件验证依赖于假设。建议在完整上下文中补充单元测试覆盖核心查询与缓存逻辑。 --- *此 Issue 由代码审查服务自动创建*
TEXT
milestone_id
INTEGER
priority
INTEGER
is_closed
INTEGER
is_pull
INTEGER
num_comments
INTEGER
ref
TEXT
deadline_unix
INTEGER
created_unix
INTEGER
updated_unix
INTEGER
closed_unix
INTEGER
is_locked
INTEGER NOT NULL (default 0
content_version
INTEGER NOT NULL (default 0
time_estimate
INTEGER NOT NULL (default 0
Update
Cancel