我使用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());
}
}
}
或者,当脚本结束时,它自己是否会这样做?
是的,当然,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结合使用 错误和错误处理
我已经研究了接口、抽象类和继承的用法。我知道每一种都有其用途,但我还是有点困惑。 我知道一般一个类只能扩展另一个类,虽然有些可能支持多个继承,但它可以实现多个接口(这可能是使用接口的主要原因)。然而,如果我是正确的,这个类也可以被另一个类扩展。我还看到抽象类可能比接口更快,并且可以有非静态的最终变量。 所以,我仍然不确定什么时候使用哪个更好。也许通过举例可以更好地理解这一点。我不反对使用任何东西,