我知道与orm合作会更好,我打算将来使用它。 但就目前而言,我正在使用这样的结构:
带有标题和日期的类Arcticle 用于数据库操作的类DataArticle 所以我没有在我的Article类中执行我的数据库操作,而是在一个单独的Data类中执行。
现在,在我的所有Data ..类中,我使用代码来执行这样的数据库操作:
public function getArticle($id){
$query = "SELECT title,date from articles where id = ?";
if ($stmt = $this->database->getConnection()->prepare($query)) {
$stmt->bind_param('i',$id);
$stmt->execute();
$stmt->bind_result($title,$date);
$stmt->store_result();
$stmt->fetch();
if(($stmt->num_rows) == 1){
$article = new Article();
$article->title = $title;
$article->date = $date;
$stmt->close();
return $article;
}else{
$stmt->close();
return null;
}
}else{
throw new Exception($this->database->getConnection()->error);
}
}
但是这样工作意味着在我的数据类中的每个函数中,我都会连接,执行语句并抛出错误。 这是很多可以使用包装器集中的重复代码。
现在我遵循关于创建数据库包装器/处理程序的建议(Throw an exception in a function or how to do descent error handling)来执行所有数据库的东西,所以它全部集中在一个类中,这使得它更容易维护。
所以我创建了这个类来开始使用PDO:
<?php
class DatabasePDO
{
private $connection;
private $host = "";
private $username = "";
private $password = "";
private $dbname = "";
public function openConnection(){
$this->connection = new PDO("mysql:host=$this->host;dbname=$this->dbname",$this->username,$this->password);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
public function getConnection(){
return $this->connection;
}
public function closeConnection(){
$this->connection = null;
}
public function insert($query, array $data){
$this->connection->prepare($query)->execute($data);
return $this->connection->lastInsertId();
}
public function update($query, array $data) {
$stmt = $this->connection->prepare($query);
$stmt->execute($data);
return $stmt->rowCount();
}
public function delete($query, array $data) {
$stmt = $this->connection->prepare($query);
$stmt->execute($data);
return $stmt->rowCount();
}
public function findOne($query, array $data = null){
$sth = $this->connection->prepare($query);
if($data != null){
$sth->execute($data);
}else{
$sth->execute();
}
if($sth->rowCount() == 1){
return $sth->fetchObject();
}else{
return null;
}
}
public function find($query, array $data = null){
$sth = $this->connection->prepare($query);
if($data != null){
$sth->execute($data);
}else{
$sth->execute();
}
if($sth->rowCount() > 0){
while($res = $sth->fetchObject()){
$results[] = $res;
}
return $results;
}else{
return null;
}
}
}
?>
但在阅读一些文章时,我发现这不是一个好习惯,因为PDO已经是一个数据库包装器。
然而,代码比以前更具可读性。 现在只是
public function getArticle($id){
$article = $this->database->find("select name, date from articles ?",array($id));
$article = new article($article->name, $article->date);
return $article;
}
这段代码要短得多,并且所有数据库逻辑都在PDO包装器类中处理,否则我将不得不在每个函数中重复包装器的代码,而我的代码将在很多地方而不是一个包装器。
有没有更好的方法来使用我的代码,或者这是我使用它的好方法。
答案 0 :(得分:1)
Dunno为什么要问或者你的疑惑,但创建数据库包装类是处理SQL查询的唯一正确方法。
虽然实施要求进行一些改进,但总体思路和用法几乎都很出色。是的,将整个屏幕的代码量减少到一行是这类课程的主要好处之一。
说到改进 - PDO有一些很好的技巧来缩短你的代码:
public function find($query, array $data = null){
$sth = $this->connection->prepare($query);
$sth->execute($data);
return $sth->fetchAll();
}
的工作方式与您的版本完全相同,但代码少了三倍
通过对基于PDO创建此类课程的敏感性的评论回答您的问题:
看,PDO已经是半DAL了。正如您所看到的,与mysqli相比,它已经有了很大的改进。虽然mysqli显然并且无疑需要创建这样的类,但PDO具有开箱即用的许多必需功能。因此,人们可以使用原始PDO。许多在PDO上创建的类确实没用。但是,PDO也可以从一些改进中受益。
看,虽然我确实改进了你的PDO代码,但是将行数减少到只有三个,基于mysqli的版本无法改进并且需要所有几十行代码。所以,3行优于12行,但find()
函数的一行行优于3行,不是吗?然而,总有一些空间可以进行更大的改进。您可以从标记维基中的List Of The Cases Where PDO Fails获得一些想法。
答案 1 :(得分:-1)
存储数据库连接的更好方法是使用单例类。
http://php.net/manual/de/language.oop5.patterns.php
<?php
class DatabasePDO
{
private static $instance;
private $connection;
private $host = "";
private $username = "";
private $password = "";
private $dbname = "";
public static function getInstance()
{
if (!isset(self::$instance)) {
self::$instance = new DatabasePDO();
}
return self::$instance;
}
public function openConnection(){
$this->connection = new PDO("mysql:host=$this->host;dbname=$this->dbname",$this->username,$this->password);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
public function getConnection(){
return $this->connection;
}
public function closeConnection(){
$this->connection = null;
}
public function insert($query, array $data){
$this->connection->prepare($query)->execute($data);
return $this->connection->lastInsertId();
}
public function update($query, array $data) {
$stmt = $this->connection->prepare($query);
$stmt->execute($data);
return $stmt->rowCount();
}
public function delete($query, array $data) {
$stmt = $this->connection->prepare($query);
$stmt->execute($data);
return $stmt->rowCount();
}
public function findOne($query, array $data = null){
$sth = $this->connection->prepare($query);
if($data != null){
$sth->execute($data);
}else{
$sth->execute();
}
if($sth->rowCount() == 1){
return $sth->fetchObject();
}else{
return null;
}
}
public function find($query, array $data = null){
$sth = $this->connection->prepare($query);
if($data != null){
$sth->execute($data);
}else{
$sth->execute();
}
if($sth->rowCount() > 0){
while($res = $sth->fetchObject()){
$results[] = $res;
}
return $results;
}else{
return null;
}
}
}
?>
使用此代码,您可以通过调用DatabasePDO :: getInstance() - &gt; getConnection();
从任何地方获取数据库连接public function getArticle($id){
$query = "SELECT title,date from articles where id = ?";
$database = DatabasePDO::getInstance();
if ($stmt = $database->getConnection()->prepare($query)) {
$stmt->bind_param('i',$id);
$stmt->execute();
$stmt->bind_result($title,$date);
$stmt->store_result();
$stmt->fetch();
if(($stmt->num_rows) == 1){
$article = new Article();
$article->title = $title;
$article->date = $date;
$stmt->close();
return $article;
}else{
$stmt->close();
return null;
}
}else{
throw new Exception($database->getConnection()->error);
}
}