如何通过PHP Session获取前页文件名并写入SQL Server访问日志
如何通过Session传递文件名到PHP访问日志页面并写入SQL Server
问题核心
你当前的问题在于前一页未正确将文件名存入Session,且日志页面过早调用session_destroy()导致Session数据被提前销毁,无法读取到文件名。另外原代码存在SQL注入风险,需要同步修复。
解决方案步骤
1. 在前一页(文件上传页)存储文件名到Session
确保在文件上传处理的页面开头先启动Session,仅在文件上传成功后将文件名存入Session:
<?php session_start(); // 必须在任何输出(HTML/echo)之前调用 // 确认文件上传成功后再获取并存储文件名 if (isset($_FILES["fileToUpload"]) && $_FILES["fileToUpload"]["error"] == UPLOAD_ERR_OK) { $fileName = basename($_FILES["fileToUpload"]["name"]); $_SESSION["uploaded_file_name"] = $fileName; // 将文件名存入Session } // 其他文件上传处理逻辑... ?>
2. 修改日志页面代码,读取Session并写入数据库
- 修复
include语句的语法错误(缺少分号) - 延迟
session_destroy()调用,待所有数据库操作完成后再销毁Session - 使用参数化查询避免SQL注入
- 新增filename字段的插入逻辑
修改后的日志页面代码:
<?php session_start(); // 必须放在最开头,输出之前调用 include 'database_connection.php'; // 补充分号修复语法错误 // 安全读取Session变量,避免Undefined Index错误 $uname = $_SESSION["user"] ?? ''; $fileName = $_SESSION["uploaded_file_name"] ?? ''; // 仅当用户名存在时执行日志写入 if (!empty($uname)) { function getUserIP() { // 获取真实访客IP(支持CloudFlare) if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) { $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"]; $_SERVER['HTTP_CLIENT_IP'] = $_SERVER["HTTP_CF_CONNECTING_IP"]; } $client = @$_SERVER['HTTP_CLIENT_IP']; $forward = @$_SERVER['HTTP_X_FORWARDED_FOR']; $remote = $_SERVER['REMOTE_ADDR']; if(filter_var($client, FILTER_VALIDATE_IP)) { $ip = $client; } elseif(filter_var($forward, FILTER_VALIDATE_IP)) { $ip = $forward; } else { $ip = $remote; } return $ip; } $user_ip = getUserIP(); $currentDate = date('Y-m-d g:i:s'); // 使用参数化查询插入主日志,避免SQL注入 $sql = "INSERT INTO ACCESS_LOGOFUSERS(ALU_USERNAME, ALU_IP, ALU_CREATEDON, ALU_FILENAME) VALUES(?, ?, ?, ?)"; $params = array($uname, $user_ip, $currentDate, $fileName); $res = sqlsrv_query($conn, $sql, $params); // 检查SQL执行结果 if ($res === false) { die(print_r(sqlsrv_errors(), true)); } // 若文件名存在,写入user_action表(同样用参数化查询) if (!empty($fileName)) { $actionSql = "INSERT INTO user_action(file_name) VALUES(?)"; $actionParams = array($fileName); $actionRes = sqlsrv_query($conn, $actionSql, $actionParams); if ($actionRes === false) { die(print_r(sqlsrv_errors(), true)); } } } session_destroy(); // 所有操作完成后再销毁Session ?>
3. 关键注意事项
- Session启动时机:
session_start()必须在任何HTML输出、echo语句之前调用,否则会触发"headers already sent"错误。 - Session销毁时机:不要在读取Session数据前调用
session_destroy(),否则Session数据会被直接清空。 - SQL注入防护:永远不要直接将用户输入(包括Session中的数据)拼接进SQL语句,使用参数化查询是最安全的做法。
- 空值检查:使用
??运算符(PHP7+)或isset()判断Session变量是否存在,避免Undefined Index警告。
内容的提问来源于stack exchange,提问作者Veronica Dsouza
相关产品推荐
相关产品推荐

