当前位置: 首页 > 知识库问答 >
问题:

PDO连接和抽象类

纪俊良
2023-03-14

我使用PDO抽象类。我想知道是否有必要每次都为$conn变量空,或者当脚本结束时它是否会这样做?

您还可以告诉我,对于这种类型的结构,取消$conn的最佳方法是什么?

abstract class DB_Connection
{
    protected static $tbl_admin = "prof_admin";
    //protected static $tbl_admin = "prof_admin";

    protected static function obj_db()
    {
        $servername = "localhost";
        $username = "root";
        $password = "";
        $dbname = "salmanshahid";
        $conn = null;

        try 
        {
            $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
            // set the PDO error mode to exception
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            return $conn;
        }
        catch(PDOException $e)
        {
            echo $sql . "<br>" . $e->getMessage();
        } 
    }
    protected static function select($query)
    {
        try 
        {
            $conn = self::obj_db();
            $stmt = $conn->prepare($query);
            $stmt->execute();

            // set the resulting array to associative
            $stmt->setFetchMode(PDO::FETCH_ASSOC); 
            return $stmt->fetchAll();
        }
        catch(PDOException $e) 
        {
            throw new Exception("Error In SELECT STATMENT: " . $e->getMessage());
        }
    }
    protected static function insert($query)
    {
        try 
        {
            $conn = self::obj_db();
            $stmt = $conn->prepare($query);
            $stmt->execute();
        }
        catch(PDOException $e) 
        {
            throw new Exception("Error In INSERT STATMENT: " . $e->getMessage());
        }
    }

}

共有1个答案

华飞驰
2023-03-14

或者,当脚本结束时,它自己是否会这样做?

是的,当然,PHP会自动关闭并清理脚本执行期间打开的所有资源,因此,不用担心手动关闭它。

不管怎样,要取消conn,只需取消它:$this-

但是,与您的类的其他问题相比,所有这些问题都是完全可以忽略不计的,这些问题是不安全的、低效的和无法使用的。

  • 首先,我不知道你为什么要把这个类抽象化。抽象类是原型类,用来作为其他类的源。但是数据库包装器是一个可以随时使用的最终类。我认为没有必要把它抽象化。
  • 错误报告也是多余和不一致的。在错误消息中添加“选择状态中的错误”是非常无用的。而连接错误处理显然是错误的。相反,让PDO抛出一个异常,然后放手。它将以与您网站中任何其他错误相同的方式处理。
  • 下一个问题是安全性。出于某种原因,无论是select()还是插入()函数都不支持预准备语句,这使得它们非常无用:您可以使用PDO::查询()来代替,结果完全相同。但是你真正需要的是正确地使用准备/执行,通过在查询中使用占位符,同时将实际变量发送到执行()
  • 另一个问题是代码重复:两个函数几乎相同。
  • 同时,这两个函数都非常不可靠:Select()函数仅限于一种类型的结果集,而插入()根本不返回任何内容。相反,您可以只使用一个函数来运行所有的查询,并使其返回语句,这将非常有用。它可以让你获得PDO支持的几十种不同格式的返回数据,甚至可以让你从DML查询中获得受影响的行数。

让我向您推荐另一种方法,一种简单的PDO包装器,它可以让您以最简单和安全的方式使用PDO:

<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_CHAR', 'utf8');

class DB
{
    protected static $instance = null;

    public function __construct() {}
    public function __clone() {}

    public static function instance()
    {
        if (self::$instance === null)
        {
            $opt  = array(
                PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES   => TRUE,
            );
            $dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHAR;
            self::$instance = new PDO($dsn, DB_USER, DB_PASS, $opt);
        }
        return self::$instance;
    }

    public static function __callStatic($method, $args)
    {
        return call_user_func_array(array(self::instance(), $method), $args);
    }

    public static function run($sql, $args = [])
    {
        $stmt = self::instance()->prepare($sql);
        $stmt->execute($args);
        return $stmt;
    }
}

它非常强大、安全且易于使用。

只需在DB::prefix:

$stmt = DB::query("SELECT * FROM table WHERE foo='bar'");

因此,首先,它是一个PDO包装器,可以通过使用magic\uu call()方法来运行任何PDO方法。我添加的唯一函数是run()

与其使用您自己的不安全和不可靠的Select()插入()方法,不如让我建议您使用一个通用的run()方法,它只不过是这三行的简写:

$stmt = DB::prepare($query);
$stmt->execute($params);
$data = $stmt->fetch();

因此,您可以将其写成一行整洁的文字:

$data = DB::run($query, $params)->fetch();

请注意,它可以运行任何类型的查询,并以PDO支持的任何格式返回结果。

我写了一篇关于这个简单包装器的文章,在这里你可以找到一些使用示例。所有示例代码都可以按原样运行,只需复制并粘贴到脚本中,然后设置凭据:http://phpdelusions.net/pdo/pdo_wrapper#samples

 类似资料:
  • 我想读关于抽象的文章,但读到不同的文章,我感到很困惑。 下面是我无法理解的问题: 1)“抽象是通过使用抽象类和接口实现的吗?”我对此进行了搜索,得到了三种类型的答案: 与此处解释的不同。 它们是相同的,只是不同的观点,就像这里解释的。 最后一个是抽象类用来实现抽象。 哪一个是真的?请举一个简单的例子。 2)“抽象意味着隐藏不必要的细节。比如专注于一个对象做什么而不是它是如何完成的。” 这是正确的吗

  • 数据库抽象层 PDO 什么是 PDO PDO(PHP Data Object),数据库访问抽象层,统一各种数据库的访问接口。 PDO支持的数据库有如下(数据来自 php 官方网站) 驱动名称 支持的数据库 PDO_CUBRID Cubrid PDO_DBLIB FreeTDS / Microsoft SQL Server / Sybase PDO_FIREBIRD Firebird/Interba

  • 问题内容: 在面试中,有人问我以下问题。我试图回答这个问题,但是我想确切回答这个问题。 如果我可以将Abstract类模拟为Interface,为什么Java提供了Interface? 这意味着如果在Abstract类中我可以将所有方法标记为abstract,然后abstract类将用作接口,那么为什么我需要接口。 谁能简单地解释一下我。 问题答案: 这是一个非常标准的面试问题。答案是:因为您可以

  • 问题内容: 谁能告诉我完全抽象的类和接口之间到底有什么区别? Abstract类也可以将其所有方法都作为abstract。接口的所有方法均为抽象。在这种情况下,两者之间的主要区别是什么? 纯抽象类和接口之间是否有区别?接口有什么用?在使用接口的地方,我们可以使用纯抽象类吗? 问题答案: 要完成以前的答案: 接口是一个“合同”。如果一个类实现一个接口,则它必须提议该接口中列出的所有服务。 抽象类是骨

  • 问题内容: 我正在为我的一个应用编写安装程序,我希望能够测试一些默认数据库设置。 使用PDO可以测试有效和无效的数据库连接吗? 我有以下代码: 我遇到的问题是该脚本尝试连接,直到60秒的脚本执行时间用完,而不是说它无法连接到数据库。 谢谢 问题答案: 您需要在连接数据库时设置错误模式: 有关更多信息,请参见以下链接: 将MySQL与PDO结合使用 错误和错误处理

  • 我已经研究了接口、抽象类和继承的用法。我知道每一种都有其用途,但我还是有点困惑。 我知道一般一个类只能扩展另一个类,虽然有些可能支持多个继承,但它可以实现多个接口(这可能是使用接口的主要原因)。然而,如果我是正确的,这个类也可以被另一个类扩展。我还看到抽象类可能比接口更快,并且可以有非静态的最终变量。 所以,我仍然不确定什么时候使用哪个更好。也许通过举例可以更好地理解这一点。我不反对使用任何东西,