如何用PHP函数从数据库读取数据并返回数组?附实现代码
嘿,我来帮你拆解这段PHP代码的合理性,以及可以优化的地方,让它更贴合生产环境的需求:
代码合理性分析
值得肯定的亮点
- 你用了预处理语句(
prepare+bind_param),这直接规避了SQL注入风险,是数据库操作里非常标准的安全实践,必须给你点个赞! - 还做了预处理语句的创建失败检查,并且抛出异常,这种主动暴露错误的方式比静默失败强太多,调试的时候能快速定位问题。
- 执行查询后调用
store_result()提前获取行数,用来判断是否有匹配结果,这个逻辑思路是通顺的。
存在的问题与优化建议
1. 返回类型不统一,调用方容易踩坑
当前代码里,没查到数据时返回字符串"...",但按照你的需求,正常情况应该返回数组。这种返回类型不一致的情况,会让调用这个函数的代码很容易出错——比如调用方本来想用foreach遍历结果,结果拿到字符串直接报错。
改进建议:没结果时返回空数组[],保持返回类型始终是数组,调用方处理起来更安全。
2. 缺失结果集读取逻辑,等于白查了
你的代码只做了查询、判断行数,但完全没写读取查询结果、组装成数组返回的逻辑——这会导致查到数据时,函数默认返回null,完全达不到你“从数据库读取值并返回数组”的需求。
这里给你两种常见的结果读取方式:
方式一:用get_result()(更简洁,需要PHP版本≥5.3.0且MySQL驱动支持)
public function avtorizacije($user) { $sql = "SELECT * FROM uporabniki_avtorizacije WHERE userId=?"; if( !$this->stmt = $this->mysqli->prepare($sql) ) { throw new Exception("MySQL Prepare statement failed: ".$this->mysqli->error); } $this->stmt->bind_param("i", $user); // 新增执行结果检查 if (!$this->stmt->execute()) { throw new Exception("MySQL Execute failed: ".$this->stmt->error); } // 获取结果集并转成关联数组 $result = $this->stmt->get_result(); $avtorizacije = $result->fetch_all(MYSQLI_ASSOC); $this->stmt->close(); // 显式关闭语句,释放资源 return $avtorizacije; // 没结果时自动返回空数组 }
方式二:用bind_result()(兼容更低版本PHP)
public function avtorizacije($user) { // 建议明确指定字段,不要用SELECT * $sql = "SELECT id, permission, created_at FROM uporabniki_avtorizacije WHERE userId=?"; if( !$this->stmt = $this->mysqli->prepare($sql) ) { throw new Exception("MySQL Prepare statement failed: ".$this->mysqli->error); } $this->stmt->bind_param("i", $user); $this->stmt->execute(); // 绑定对应字段 $this->stmt->bind_result($id, $permission, $createdAt); $avtorizacije = []; // 循环读取每一行结果 while ($this->stmt->fetch()) { $avtorizacije[] = [ 'id' => $id, 'permission' => $permission, 'created_at' => $createdAt ]; } $this->stmt->close(); return $avtorizacije; }
3. 建议显式释放资源
你的代码没有关闭预处理语句($this->stmt->close()),虽然PHP脚本结束后会自动回收资源,但显式关闭是更严谨的编程习惯,尤其是在长时间运行的脚本中,能避免不必要的资源占用。
4. 尽量别用SELECT *
建议明确写出需要查询的字段,而不是用SELECT *:
- 减少不必要的数据传输,提升查询性能;
- 避免后续表结构变更(比如新增/删除字段)导致的代码意外问题,让逻辑更健壮。
5. 补充执行阶段的错误检查
除了预处理创建失败,还可以对execute()的结果做检查,捕获执行阶段的错误(比如数据库权限不足、字段不存在等),让错误处理更全面。
额外的技术小建议
如果你的项目版本允许,推荐用PDO替代mysqli——PDO支持更多数据库类型,API更简洁,处理结果集也更方便(比如直接用fetchAll()),代码可读性和复用性都会更高。
内容的提问来源于stack exchange,提问作者zupko
相关产品推荐
相关产品推荐

