使用通用函数查询数据库是不好的做法吗?

时间:2013-06-26 14:08:36

标签: php mysql database pdo

我正在编写一个webapp,可以在内部用于各种任务。 它使用MySQL数据库,经常需要查询数据。

我知道准备好的语句并且它们是最佳实践,但是考虑到大量的表和连接,我发现最简单的方法就是编写一个接受查询的常规函数​​,运行它并返回结果。

我知道如果它在实际网站上,这可能容易受到SQL注入的影响但是使用这种方法有什么本质上的不好吗?我对php和MySQL之间的接口相对较新,并且有兴趣了解在webapp中运行语句的可重复方法的最佳实践。

以下是我将用于SELECT查询的示例函数。

function getSQLResultsPDO($query){
  $mydb = new PDO('mysql:host=localhost;dbname=mydatabase;charset=utf8', 'user', 'password');
  $sth = $mydb->prepare($query);
 if (!$sth) {
    echo "\n<pre>PDO::errorInfo():</pre>\n";
    echo "<pre>";
    print_r($conn->errorInfo());
    echo "</pre>";
}
  $sth->execute();

  $result = $sth->fetchAll(PDO::FETCH_CLASS);
  if (empty($result)){
    $result = false;
  }

  return $result;

}

2 个答案:

答案 0 :(得分:5)

我只能同意@jay harris的评论:“关于该脚本的一切都是不好的做法”

虽然使用这样一个函数来处理数据库唯一理智的选择,但实现完全错误。

首先,为什么你认为这样的功能与准备好的陈述相矛盾?为什么不添加一个额外的参数 - 一个包含数据的数组 - 并且具有功能和安全性?

接下来,正如您已经被告知的那样,不要为每个查询连接,而是每个应用程序一次

最后,你的错误处理方式是错误的。

function getSQLResultsPDO($query, $params = array(), type = PDO::FETCH_CLASS){
  global $mydb;
  $sth = $mydb->prepare($query);
  $sth->execute($params);
  return $sth->fetchAll($type);
}

它不是很方便,但至少它是可用的,95%安全。

使用此功能一段时间后,您会发现只有一个功能非常不方便。最终你会发现你需要一组功能。一个运行不返回行的DML查询,一些函数返回不同类型的结果。

比较这两个代码:

$data = getSQLResultsPDO("SELECT name FROM users WHERE id=?", array($id));
if (isset($data[0]->name)) {
    $name = $data[0]->name;
}
//and
$name = getSQLscalar("SELECT name FROM users WHERE id=?", array($id));

答案 1 :(得分:0)

这可能是一个很好的做法。如果你看一下框架,他们会实现类似的东西,除了它更复杂,它们允许你使用不同的方法创建你的查询。这样做的目的是集中查询,如果所有查询都通过相同的路径,则更容易修改涉及所有查询的内容。例如,如果您想将数据库从MySQL更改为其他内容。此外,你可以在这个中心点防止注射。

所以,你的想法很好,但有些东西当然可以改进。您可以在打开应用程序时创建单个连接,并将其用于稍后运行的每个查询。如果您的查询方法在类中,则连接可以是类属性,例如,在构造函数中初始化的属性。

我的建议是看看其他人是如何做到的,并从中获取灵感。例如,看看框架如何处理这些东西。

此外,还有一个很好的MVC教程也谈到了这个东西,这里是:

http://johnsquibb.com/tutorials