当我选择不存在的表时,PDO没有捕获错误


PDO not catching error when I SELECT a table that doesn't exist

我正在尝试/捕获PDO::query以确保表是否存在。但是,它不是捕获错误并返回 true 或 false,它只是抛出一个未捕获的错误:

public function __construct(){
    $this->db = parent::connect();
}
public function table_exists($table){
        try {
            $this->query("SELECT 1 FROM `$table` LIMIT 1");
            return true;
        } catch (Exception $e) {
            return false;
        }
    }
    public function query($sql){
        try {
            $this->result = $this->db->query($sql);
            return $this;
        } catch (Exception $e) {
            return null;
        }
    }

我也在尝试中尝试了这个$this->db->setAttribute('PDO::ATTR_ERRMODE, 'PDO::ERRMODE_EXCEPTION);,但它没有任何区别。所以我得到

致命错误:未捕获的异常"PDOException",并显示消息 'SQLSTATE[42S02]:找不到基表或视图:1146 表 "refritec.user"不存在" ...''DatabaseDriverMysql.php:34 堆栈跟踪: 0 ...''DatabaseDriverMysql.php(34): PDO->query('SELECT 1 FROM ...') 1 ...''DatabaseDriverMysql.php(25): Core''DatabaseDriver->query('SELECT 1 FROM '...') 2 ...''笔.php(123): Core''DatabaseDriver->table_exists('user') #3 [内部函数]: Core''Pen->update() #4 ...''index.php(97): call_user_func_array(数组,数组)#5 {main} 扔进去 ...''DatabaseDriverMysql.php 在第 34 行

除了评论中解释的那个愚蠢的错别字之外,你的方法本质上是错误的。

首先,您没有检查特定的异常。意味着如果出现任何错误,不仅缺少表,还会有误报。

其次,你的代码容易被SQL注入。

第三,您正在编写一个故意引发错误的代码。这又是错误的。只要有办法以常规方式检查表是否存在,就必须使用它:

$stmt = $pdo->prepare("SHOW TABLES LIKE ?");
$stmt->execute([$table]);
return $stmt->fetchColumn();

第四,这样的功能本身就会引起数据库设计的怀疑。在设计合理的应用程序中,无需动态创建表。

我无法重现您的确切问题,但您是否尝试捕获以下PDOException

try {
    $this->query("SELECT 1 FROM `$table` LIMIT 1");
    return true;
} catch (PDOException $e) {
    return false;
}

编辑

您还必须在连接上使用$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);。 因为PDO默认情况下不会引发异常,如下所示。

我使用简单的查询来查看表是否存在,如果值与"0"不同,则有一个值,我可以显示我想要的消息。

    $res = $this->db->query("SHOW TABLES LIKE '".$tbname."perfil'");
    $count = $res->num_rows();