分步详细讲解一下下面的php代码。请在正文区域显示:
/** 写入at表 **/
$reg = "/@([^@\s]+)/"; //正则匹配,得到@的用户
$match = array();
preg_match_all($reg,$content,$match); //得到@用户数组
$users_array = array_unique($match[1]); //去掉重复用户名
if($users_array){
$count = count($users_array); //@的用户总数
/**查看@用户是否存在,如果存在写入at表**/
for($i = 0;$i < $count; $i++){
$select_sql = "select id from mr_user where username = '".$users_array[$i]."'";
$user_id = $db->single($select_sql,MYSQL_ASSOC);
if($user_id){
$insert_sql = "insert into mr_at (user_id,post_id)
values ( :user_id , :post_id)";
$db->query($insert_sql,array('user_id'=>$user_id,'post_id'=>$post_id));
}
}
}代码功能概述
该PHP代码实现从文本内容中提取@提及的用户名,验证用户存在性后,将有效用户ID与外部传入的帖子ID关联写入数据库的mr_at表。
分步详细解析
1. 正则表达式匹配
$reg = "/@([^@\s]+)/"; // 匹配@后跟非@非空格的字符串
@([^@\s]+):正则表达式分解@:匹配字面量@符号([^@\s]+):捕获组,匹配非@和非空白字符的连续序列例如:文本中
@张三 @李四会被匹配为张三和李四
2. 执行匹配并去重
preg_match_all($reg, $content, $match); // 获取所有匹配结果 $users_array = array_unique($match[1]); // 去除重复用户名
preg_match_all返回多维数组,$match[1]包含所有被匹配的用户名array_unique确保同一用户名不会被重复处理
3. 循环验证并写入数据库
if($users_array){ // 仅当存在@用户时执行
for($i = 0; $i < $count; $i++){ // 遍历每个用户名
$select_sql = "select id from mr_user where username = '".$users_array[$i]."'";
$user_id = $db->single($select_sql, MYSQL_ASSOC);
if($user_id){ // 用户存在时执行插入
$insert_sql = "insert into mr_at (user_id, post_id)
values (:user_id, :post_id)";
$db->query($insert_sql, array('user_id'=>$user_id, 'post_id'=>$post_id));
}
}
}查询用户ID:通过用户名在
mr_user表中查找用户ID参数化插入:使用命名参数
:user_id和:post_id防止SQL注入关联存储:将有效的用户ID与外部传入的
$post_id存入mr_at表
潜在问题与改进建议
安全性风险:
直接拼接SQL查询(
$select_sql)存在注入风险,建议改用预处理语句代码中
$db对象未初始化说明,需确保数据库连接安全性能优化:
多次单独查询用户ID(
$count次)效率较低,可改为批量查询缺乏错误处理机制(如数据库操作失败时)
代码健壮性:
未处理
$content为空的情况未验证
$post_id是否有效建议添加日志记录关键操作
执行流程示意图
输入文本 → 2. 正则提取@用户 → 3. 去重 → 4. 验证用户存在性 → 5. 写入关联表