[在最近的一个有趣的项目(用于管理账单和客户的系统中,我决定使用PDO作为数据库接口。我遇到了一个问题,就是在使用准备好的语句(准备,设置参数,执行等)时,我一直在编写相同的代码,因此我决定编写一个小助手类,其中包含使用速度更快的方法(select,selectRow,等)。
我知道这不是最佳选择,而且PDO本身已经“足够好”(我已经阅读了有关PDO助手类的其他问题),但是我的问题更多地涉及使用(静态)助手类时的常规设计。 !
这里是我的第一种方法的代码
class DBA {
private $con;
public function __construct () {
$this->con = new PDO ( .. );
}
public function select ($query, $params = array()) {
$sth = $this->con->prepare($query);
....
}
// returns an object
public function fetchObject ($query, $params = array(), $class) {
$sth = $this -> con -> prepare($query);
$sth -> setFetchMode(PDO::FETCH_CLASS, $class);
..
}
...
}
class Bill {
public $date;
public $payed;
// ...
public function markAsPayed () {
$dba = new DBA();
if($dba -> exec ('UPDATE ..', $args)) {
return true,
}
return false;
}
}
// index.php
$dba = new DBA ();
$bill = $dba -> fetchObject ('SELECT ..', $args, 'Bill');
$bill -> markAsPayed();
我发现了以下问题:我通过创建类的实例在其他类中使用该类(例如,在从数据库行中获取的对象中)。因此,将有大量的辅助类实例(这意味着大量的连接),因为我正在使用辅助类的其他类的每个方法中创建一个实例。当我调用使用helper类的方法时,在由helper类创建的对象上,整个应用程序变得非常慢。
将助手类设为静态是一个好的解决方案吗?如果是这样,我如何连接到数据库?我应该使用单例模式吗?我不想在helper类的每个方法中都重新连接到数据库,但是在helper类中具有全局连接。
您需要这样的课程:
class DataBase {
public $conn;
public $queryCount = 0;
public $queries = array();
static private $instance;
public function __construct()
{
$this->conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD);
mysqli_select_db($this->conn, DB_NAME);
mysqli_set_charset($this->conn, 'utf8');
}
static public function instance()
{
if (!isset(self::$instance)) {
$name = __CLASS__;
self::$instance = new $name;
}
return self::$instance;
}
public function esc($str)
{
if (is_null($str)) return null;
return mysqli_real_escape_string($this->conn, $str);
}
public function escape($str)
{
if (is_null($str)) return null;
return mysqli_real_escape_string($this->conn, $str);
}
public function escapeArray($arr)
{
foreach ($arr as $k => $v) {
if (!is_null($v)) {
$arr[$k] = $this->escape($v);
}
}
return $arr;
}
public function lastError() {
return mysqli_error($this->conn);
}
public function query($query)
{
$this->queryCount++;
$this->queries[] = $query;
$result = mysqli_query($this->conn, $query);
if ($result === false) {
$this->debug($query);
}
if (mysqli_num_rows($result) == 0) {
return array();
}
$salida = array();
while ($row = mysqli_fetch_assoc($result)) {
$salida[] = $row;
}
mysqli_free_result($result);
return $salida;
}
public function count($table, $opts = array())
{
$where = "";
if (!empty($opts['where'])) {
$where = $this->where($opts['where']);
}
$query = "SELECT COUNT(*) AS result FROM $table $where";
$row = $this->queryOne($query);
return (int)$row['result'];
}
public function lastId()
{
return mysqli_insert_id($this->conn);
}
protected function debug($query)
{
//echo "<br>Error in the sentence: ". $query . "<br>";
//echo mysqli_error();
//$e = new Exception();
//pr($e->getTraceAsString());
}
public function insert($table, $data)
{
$this->queryCount++;
$fields = $this->escapeArray(array_keys($data));
$values = $this->escapeArray(array_values($data));
foreach ($values as $k => $val) {
if (is_null($val)) {
$values[$k] = 'NULL';
} else {
$values[$k] = "'$val'";
}
}
$query = "INSERT INTO $table(`".join("`,`",$fields)."`) VALUES(".join(",", $values).")";
$this->queries[] = $query;
return mysqli_query($this->conn, $query);
}
public function execute($query)
{
$this->queryCount++;
$this->queries[] = $query;
return mysqli_query($this->conn, $query);
}
public function multiExecute($multiQuery)
{
$this->queryCount++;
$this->queries[] = $multiQuery;
return mysqli_multi_query($this->conn, $multiQuery);
}
public function getAffectedRows()
{
return mysqli_affected_rows($this->conn);
}
public function select($table, $opts = array())
{
$fields = "*";
$where = '';
$order = '';
if (!empty($opts['fields'])) {
if (is_array($opts['fields'])) {
$fields = join(",", $opts['fields']);
} else {
$fields = $opts['fields'];
}
}
if (!empty($opts['where'])) {
$where = $this->where($opts['where']);
}
if (!empty($opts['order'])) {
$order = "ORDER BY " . $opts['order'];
}
$query = "SELECT $fields FROM $table $where $order";
if (!empty($opts['limit'])) {
if ($opts['limit'] === 1 || $opts['limit'] == '1') {
return $this->queryOne($query." LIMIT 1");
}
$query .= " LIMIT ".$opts['limit'];
}
return $this->query($query);
}
public function selectOne($table, $opts = array())
{
$opts['limit'] = 1;
return $this->select($table, $opts);
}
public function update($table, $data, $opts = array())
{
$where = "";
if (!empty($opts['where'])) {
$where = $this->where($opts['where']);
}
$update = array();
foreach ($data as $field => $value) {
if (is_null($value)) {
$update[] = "`$field` = NULL";
} else {
$update[] = "`$field` = '".$this->esc($value)."'";
}
}
$query = "UPDATE $table SET ".join(" , ", $update)." $where";
return $this->execute($query);
}
}
请参阅here以获取完整的课程