经典的第一个班轮 - 在SO上看到了类似的问题,但没有一个能真正帮助我理解我所处的十字路口。
代码之前的一点背景 - 我不是PHP或PDO的新手(虽然也不是专家),但我是面向对象PHP的完全新手,我正试图在何时使用类和何时获得平衡这可能是矫枉过正的。
我希望答案分为两部分。首先,最好在使用PDO时创建包装器数据库类 - 用于连接,基本查询等。
其次,如果没有 - 是否有更好的方法来加快查询编写速度?
编辑虽然我在质疑下面的代码,但实际上我总体上质疑PDO包装类方法 - 所以下面的类可能比这要大得多,但有没有需要/好处?< / p>
请参阅以下代码; 注意:通过config.php中的spl_autoload_register()调用类文件
class_database.php
class Database
{
private $conn;
public function __construct() {
$this->openConnection();
}
public function openConnection() {
try {
$this->conn = new PDO('mysql:host=' . DB_SERVER . '; dbname=' . DB_NAME, DB_USER, DB_PASS);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'There was an error connecting to the database, Error: ' . $e->getMessage();
die();
}
}
public function getAll($sql, array $params) {
$stmt = $this->conn->prepare($sql);
$stmt->execute($params);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
}
generic_file.php
require_once '../includes/config.php';
$dbh = new Database();
$sql = ("SELECT * FROM users where id = :id and username = :username");
$id = 1;
$username = 'craig';
$params = array(':id' => $id,
':username' => $username);
$row = $dbh->getAll($sql, $params);
var_dump($row);
现在,对我而言,这似乎毫无意义。单独使用PDO而不是包装类,这个查询就像编写一样简单。除此之外 - 如果我想使用不同的fetch方法 - 我必须在类中编写更多方法。 此外,以前我使用了一个简单的函数来实例化并返回一个新的PDO对象,只是包含该文件并将一个变量赋值给函数返回很简单 - 再次我认为类方法是过度的。
另外,使用上面的代码,并通过在类中执行此操作,我不会失去“准备”语句的好处,因为我必须每次都传递sql语句,甚至只是为了更改变量同样的声明?
但是,我在网上找到了很多例子,尤其是我目前使用的Lynda.com的数据库包装类。最重要的是 - 我不是专家,因此我认为矫枉过正可能是最佳实践并且强烈推荐,因此请各位专家帮助我!
所以......回到我的问题 - 在使用PDO时是否有充分的理由使用这样的课程? 如果没有,是否有其他DRY方法,其他人使用这种方法来最小化使用PDO查询所需的代码行?
提前致谢。
答案 0 :(得分:1)
我一次有同样的问题。
抽象数据库的好处是可以确保所有连接都正确无误,如果您确实需要更改数据库类型,则只需要更改代码的一个位置。它还可以更容易地检查发出的查询,因为您知道如果您在类中回显并退出,则所有查询都将被检查。
我解决它的方法是创建一个类,其中构造函数建立连接并将其分配给私有变量,同时也在数据库中设置表。 最好的方法是使用一些公共函数来创建,检索,更新和删除。有时称为CRUD。 对于每个函数,唯一和第一个参数是数组。为了创建它,需要数组并使用它创建一个准备好的语句然后执行它。 它与其他人做了非常类似的事情,但是对于检索数组是匹配的内容,对于更新,它采用以id结尾的内容并将其余部分设置为更新id =提供的位置,并且对于删除它将删除所有的keys =表中的值。
编辑: 这是我在课堂上放的删除功能。如果参数的值之一是数组,它将准备语句并循环通过它。这仅适用于一个变量。您也可以使用它来传递数组,其中数值索引的值是您想要插入的数组,但这不是我设置代码的方式。
public function delete($info) {
$dbh = $this->dbh;
if (isset($info['submit_action'])) unset($info['submit_action']);
$where = array();
foreach (array_keys($info) as $name) {
$where[] .= "$name = :$name";
}
//echo "DELETE FROM {$this->table_name} WHERE " . implode(" AND ", $where) . ";"; exit;
$data = $dbh->prepare("DELETE FROM {$this->table_name} WHERE " . implode(" AND ", $where) . ";");
foreach ($info as $name => $value) {
if ($array_value == $name) $data->bindParam(":$name", $array_info);
else $data->bindValue(":$name", trim($value));
}
foreach ($info as $name => $value) if (is_array($value)) { $array_value = $name; break; }
if (isset($array_value)) {
foreach ($info[$array_value] as $array_info) {
try {
$data->execute();
}
catch (PDOException $e) {
if (!is_null($this->error_msg))
handle_error($this->error_msg, $e->getMessage());
else
handle_error("There was a problem removing the {$this->subject}.", $e->getMessage());
}
}
} else {
try {
$data->execute();
}
catch (PDOException $e) {
handle_error(/*public error msg - could set this anyway you want*/, $e->getMessage());
}
}
// Send success msg
}