PHP5升级至PHP7时mysqli_real_escape_string()报错问题排查
解决PHP7迁移中mysqli_real_escape_string()参数为null的登录报错
这个报错Warning: mysqli_real_escape_string() expects parameter 1 to be mysqli, null given是PHP5转PHP7 mysqli时的典型问题,我帮你拆解原因并给出修复方案:
问题定位
- 变量作用域缺失:你的
make_safe函数内部用到了$link数据库连接变量,但这个变量是在函数外部(config.php中)定义的,PHP函数默认无法访问全局作用域的变量,导致函数里的$link是null,直接触发报错。 - 潜在连接初始化问题:还要确认
config.php里确实成功创建了有效的mysqli连接实例$link,如果连接配置错误或失败,$link也会是null。
修复步骤
1. 修复make_safe函数的作用域问题
有两种简洁的修复方式,任选其一即可:
方式一:在函数内声明使用全局变量
修改make_safe函数,添加global $link引入全局作用域的数据库连接:
function make_safe($variable) { global $link; // 声明使用外部全局的$link变量 $variable = strip_tags(mysqli_real_escape_string($link, trim($variable))); return $variable; }
方式二:将$link作为参数传递给函数
这种方式更符合代码封装的最佳实践,避免依赖全局变量:
// 修改函数定义,接收连接对象作为参数 function make_safe($link, $variable) { $variable = strip_tags(mysqli_real_escape_string($link, trim($variable))); return $variable; } // 调用时传递$link(示例以管理员登录SQL为例) $sql= mysqli_query($link, "SELECT *,b.branch_name FROM tbl_add_admin aa left join tblbranch b on b.branch_id = aa.branch_id WHERE aa.email = '".make_safe($link, $_POST['username'])."' and aa.password = '".make_safe($link, $_POST['password'])."'");
2. 验证config.php的数据库连接
打开config.php,确保里面的mysqli连接代码正确,示例如下:
// 替换成你的实际数据库配置 define('DB_HOST', 'localhost'); define('DB_USER', 'your_db_username'); define('DB_PASS', 'your_db_password'); define('DB_NAME', 'your_db_name'); // 创建mysqli连接 $link = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME); // 检查连接是否成功,失败时直接输出错误 if (!$link) { die("数据库连接失败: " . mysqli_connect_error()); }
如果连接配置有误,这段代码会直接输出错误信息,方便你快速排查。
额外优化建议(可选但推荐)
手动使用mysqli_real_escape_string虽能解决当前问题,但仍存在SQL注入风险,更安全的方案是使用mysqli预处理语句,示例如下(以管理员登录为例):
if($_POST['ddlLoginType'] == '1'){ // 准备预处理语句 $stmt = mysqli_prepare($link, "SELECT *,b.branch_name FROM tbl_add_admin aa left join tblbranch b on b.branch_id = aa.branch_id WHERE aa.email = ? and aa.password = ?"); // 绑定参数("ss"表示两个字符串类型的参数) mysqli_stmt_bind_param($stmt, "ss", $_POST['username'], $_POST['password']); // 执行语句 mysqli_stmt_execute($stmt); // 获取结果集 $sql = mysqli_stmt_get_result($stmt); }
预处理语句会自动处理参数转义,彻底规避SQL注入,同时也能避免类似的变量作用域问题。
修改完成后测试登录功能,应该就能正常使用了。
内容的提问来源于stack exchange,提问作者Ahmet
相关产品推荐
相关产品推荐

