PHP - 开始准备语句但它们看起来很笨拙

时间:2012-06-05 07:31:24

标签: php mysql pdo

我有一个网站,我连接到mySQL数据库,以通常的方式进行大量查询。我没有做比以下更复杂的事情:

$result = mysql_query('SELECT * FROM table WHERE condition = "'.mysql_real_escape_string($_POST['condition']).'"');
$row = mysql_fetch_assoc($result);
echo $row['var1'].' '.$row['var2'];

它有效。但是我一直在阅读准备好的语句,它们似乎提供了更多的安全性,我想使用它们并用一些准备好的语句替换我的数据库调用,所以我一直在查看mysqli类。

但实现同样的事情似乎还有更多的代码。我明白为了得到上述内容,我必须这样做:

$stmt = $db->stmt_init();
if($stmt->prepare('SELECT * FROM table WHERE condition = ?')) {
$condition = $_POST['condition'];
$stmt->bind_param('s', $condition);
$stmt->execute();

$stmt->bind_result($var1, $var2, ...);
if ($stmt->fetch()) {
    echo $var1 . ' - ' . $var2;
}
}

所以它看起来像是一堆更多的代码,并且更难以管理。我是否误解了如何使用这些或者是否有更简单的方法来执行“正常”的PHP事务:

  • 填充$ row,是一个表示数据库中一行的数组。
  • 循环遍历行,并使用“下一行”重新填充$行。
  • 正常更新查询。

以上都很好并且很快“通常”做,但看起来他们会使用预备语句来占用更多行。

1 个答案:

答案 0 :(得分:0)

一种常见的方法是将数据库功能包装到类中。这是一个实现缓存预准备语句的简单方法:

class DB {
  protected $db;
  protected $cache;

  public function __construct($host, $database, $user, $pass, $charset = 'utf8') {
    $this->db = new PDO(sprintf('mysql:dbname=%s;host=%s', $database, $host, $charset),
                        $user, $pass);
    $this->cache = array();
    $this->db->query(sprintf('SET NAMES %s', $charset));
  }

  public function query($query, $vars = array()) {
    //You may input a simple value, no need for arrays with a single argument                              
    if (!is_array($vars))
      $vars = array($vars);

    //Short names inside the function                                                                      
    $db = &$this->db;
    $cache = &$this->cache;

    //Ensure the prepared statement is in cache                                                            
    if (!isset($cache[$query]))
      $cache[$query] = $db->prepare($query);

    //Execute the statement and return all rows                                                            
    $stmt = $cache[$query];
    if ($stmt->execute($vars))
      return $stmt->fetchAll();
    else
      return false;
  }
}

这与旧的数据库接口非常接近。例如:

$db = new DB(host, database, user, pass);
$result = $db->query('SELECT id, name FROM table WHERE id = ? AND address = ?',
                     array(42, 'home'));
foreach ($result as $row) {
  ...
}