这是PDO的“好代码"包装器吗?有没有潜在的问题? [英] Is this wrapper for PDO 'good code' ? Are there any potential problems?
问题描述
我构建了此类与PDO配合使用,以使SQL查询更轻松",而不必担心.
I built this class to work with PDO, to make SQL queries 'easier' and less to worry about.
这是我的想法
- 是否更像类DB扩展了PDO?
- 查询方法是否太大?是否应该将其拆分为称为..的私有方法?这就是所谓的松耦合?
- 我自己检测SELECT查询是否太丑陋了?
- 还有其他明显的问题吗?因为我有点像边走边学,所以我确定自己已经忽略了很多潜在的问题.
- Should it be more like class DB extends PDO?
- Is the query method too big? Should it be split into private methods which are called.. is this what is known as loose coupling?
- Is my way for detecting a SELECT query too ugly for it's own good?
- What other problems are evident? As I am sort of learning-as-I-go, I'm sure I could have overlooked a lot of potential problems.
谢谢
`
class Db
{
private static $_instance = NULL;
private function __construct() {
// can not call me
}
private function __clone() {
// no!
}
public static function getInstance() {
if (!self::$_instance)
{
try {
self::$_instance = new PDO('mysql:host=' . CONFIG_MYSQL_SERVER . ';dbname=' . CONFIG_MYSQL_DATABASE, CONFIG_MYSQL_USERNAME, CONFIG_MYSQL_PASSWORD);;
self::$_instance-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
trigger_error($e->getMessage());
}
}
return self::$_instance;
}
public static function query($query /*string*/, $bindings = NULL)
{
$queryPortion = substr($query,0, 6);
try {
if ($bindings) {
$prepared = self::getInstance()->prepare($query);
foreach($bindings as $binding=>$data) { // defaults to string
if (!is_array($data)) {
$prepared->bindParam($binding, $data);
} else {
switch(count($data)) {
case 1:
$prepared->bindParam($binding, $data['value']);
break;
case 2:
$prepared->bindParam($binding, $data['value'], $data['dataType']);
break;
case 3:
$prepared->bindParam($binding, $data['value'], $data['dataType'], (int)$data['length']);
break;
default:
trigger_error('An error has occured with the prepared statement bindings.');
return false;
break;
}
}
}
$prepared->execute();
return $prepared->fetchAll(PDO::FETCH_ASSOC);
} else if (String::match($queryPortion, 'select')) { // if this is a select query
$rows = self::getInstance()->query($query);
return $rows->fetchAll(PDO::FETCH_ASSOC);
} else {
return self::getInstance()->exec($query);
}
}
catch(PDOException $e)
{
trigger_error($e->getMessage());
}
}
public static function getLastInsertId()
{
try {
self::getInstance()->lastInsertId();
}
catch(PDOException $e)
{
trigger_error($e->getMessage());
}
}
public static function disconnect()
{
// kill PDO object
self::$_instance = NULL;
}
}
推荐答案
这还不错,并且据说它可能对小型应用程序有所帮助,尽管它基本上是对另一个抽象的非常薄的抽象.它并没有带来很多其他功能.
It's not bad and as it's been said it might help for small applications although it's mostly a very thin abstraction on another abstraction. It's not bringing a lot of others functionalities.
您可能要考虑的其他事项:
Something you might want to consider, amongst other things:
- 由于这是PHP5代码,因此请使用例外代替
trigger_error
和也可能通过query()
方法返回结果集. - 在
new PDO
行的末尾有两个分号(;;
).
- As this is PHP5 code, use exceptions instead of
trigger_error
andset_exception_handler
if necessary until exceptions are more widespread, but it's definitely cleaner and more future-proof. - You are using a singleton, it's not a bad thing necessarily but in this case, for example, one shortcoming will be that you'll only be able to handle one connection to one database.
- I don't know if you make use of stored procedures, but a stored procedure might return a result set through the
query()
method too. - You have two semi-colons (
;;
) at the end of yournew PDO
line.
话虽这么说,我认为您的查询方法不会太大,并且目前还无法从那里的其他地方调出很多东西.尽管一看到可以从另一个函数调用的两三行,就将其拆分.这是 DRY 的好方法.
That being said, I don't think your query method is too big and there's not much that could be recalled from elsewhere in there at the moment. Though as soon as you see two or three lines that could be called from another function, split it. That's a good way to DRY.
这篇关于这是PDO的“好代码"包装器吗?有没有潜在的问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!