You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OOP PHP登录注册系统数据库查询报错求助

问题分析与修正方案

核心错误点

  1. 变量名大小写/下划线不一致:DB类中私有属性定义为$_PDO,但构造函数里用$this->pdo,query方法里调用$this->_pdo——PHP变量名区分大小写,导致PDO实例无法传递到query方法,直接触发致命错误。
  2. 中文引号导致配置失效:init.php里'db' => ‘my_db’使用了中文单引号,会被当作数据库名的一部分,PDO无法找到目标数据库。
  3. 查询未执行:query方法仅做了语句准备(prepare),没有调用execute()发送查询请求,就算prepare成功也不会有实际数据库操作。
  4. 错误处理缺失:未处理prepare、execute失败的情况,无法定位问题所在。

修正后的代码

DB.php

<?php
class DB {
    private static $_instance = null;
    // 统一变量名为$_pdo,避免大小写混淆
    private $_pdo, 
            $_query, 
            $_error = false, 
            $_results, 
            $_count = 0;

    private function __construct() {
        try {
            $this->_pdo = new PDO(
                'mysql:host=' . Config::get('mysql/host') . ';dbname=' . Config::get('mysql/db'),
                Config::get('mysql/username'),
                Config::get('mysql/password')
            );
            // 开启PDO异常错误模式,便于调试
            $this->_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            echo 'Connected';
        } catch(PDOException $e) {
            die($e->getMessage());
        }
    }

    public static function getInstance(){
        if(!isset(self::$_instance)){
            self::$_instance = new DB();
        }
        return self::$_instance;
    }

    public function query($sql, $params = array()) {
        $this->_error = false;
        // 处理prepare失败的情况
        if(!($this->_query = $this->_pdo->prepare($sql))) {
            $this->_error = true;
            return $this;
        }
        // 执行查询并处理参数绑定
        try {
            if(!$this->_query->execute($params)) {
                $this->_error = true;
            }
            // 保存结果集与行数
            $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
            $this->_count = $this->_query->rowCount();
            echo 'Query Success';
        } catch(PDOException $e) {
            $this->_error = true;
            die($e->getMessage());
        }
        return $this;
    }

    // 新增方法,方便外部获取结果、错误状态和行数
    public function results() {
        return $this->_results;
    }

    public function error() {
        return $this->_error;
    }

    public function count() {
        return $this->_count;
    }
}

init.php

<?php
session_start();

$GLOBALS['config'] = array(
    'mysql' => array(
        'host' => '127.0.0.1',
        'username' => 'root',
        'password' => 'root',
        // 替换中文单引号为英文单引号
        'db' => 'my_db'
    ),
    'remember' => array(
        'cookie_name' => 'hash',
        'cookie_expiry' => 2628288
    ),
    'session' => array(
        'session_user' => 'user'
    )
);

spl_autoload_register(function($class) {
    require_once 'classes/' . $class . '.php';
});

require_once 'functions/sanitize.php';

index.php(优化后可查看结果)

<?php 
require_once 'core/init.php';

$db = DB::getInstance();
$db->query('SELECT username FROM users');

// 输出查询结果或错误信息
if(!$db->error()) {
    echo '<pre>';
    print_r($db->results());
    echo '</pre>';
    echo 'Total users: ' . $db->count();
} else {
    echo 'Query failed';
}
?>

修正说明

  1. 统一PDO实例的变量名,确保构造函数和query方法调用的是同一个属性。
  2. 替换配置中的中文引号,保证数据库名正确读取。
  3. 在query方法中添加execute()执行查询,同时保存结果集和行数,方便后续使用。
  4. 开启PDO异常模式,新增错误状态和结果获取方法,便于调试和业务逻辑处理。

内容的提问来源于stack exchange,提问作者user3931227

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 13:10:23