好吧,您必须将每个参数的值添加到缓存键中。像这样的:
public function stmt($sql, $params) {
$cache_key = sha1($sql . serialize($params));
if( $result = cache::get($cache_key) ) {
return $result;
}
$sth = $this->connection->prepare($sql);
$i = 0;
foreach ($params as &$param)
{
$sth->bindParam(++$i, $param);
$sth->execute();
}
unset($param)
// fetch all the rows into $result
cache::set($cache_key, $result);
return $result;
}
$obj->stmt('SELECT * FROM table WHERE id = ?', array(&$id));
我会把它留给你来适应你的需要。您必须获取行并将它们存储在一个数组中。
这是您必须使用的包装器:
class stmt
{
protected $sth, $sql, $cache, $params = array();
public function __construct($dbh, $sql)
{
$this->sth = $dbh->prepare($sql);
$this->sql = $sql;
}
public function bindParam($param, &$var)
{
$this->params[$param] =& $var;
return $this->sth->bindParam($param, $var);
// or, if you want to support all the args
$args = func_get_args();
$args[1] =& $var;
return call_user_func_array(array($this->sth, 'bindParam'), $args);
}
public function execute(array $params = null)
{
$str = serialize(isset($params) ? $params : $this->params);
$cache_key = sha1($this->sql . $str);
// insert cache logic here...
if (isset($params))
{
$this->stmt->execute($params);
}
else
{
$this->stmt->execute();
}
$this->cache = $this->stmt->fetchAll();
// save cache here
}
public function fetch()
{
return array_shift($this->cache);
}
}
您必须匹配您计划使用的每个 PDOStatement 方法。 PDO::FETCH_INTO 也很难实现。我的建议:专注于你自己的使用。也许您甚至不必在 dbh 级别实现缓存,而是可以只在需要的地方添加缓存功能。
无论如何,请记住,您编写的代码越多,您需要维护的代码就越多,您就越有可能在应用程序中引入错误。所以要小心缓存层的成本/收益分析,因为它会为了自己的利益而过于聪明:)