Php 模拟PDO语句::执行
我试图用Memcache中的函数扩展我的PDO类。特别是,我创建了一个调用Php 模拟PDO语句::执行,php,caching,pdo,memcached,Php,Caching,Pdo,Memcached,我试图用Memcache中的函数扩展我的PDO类。特别是,我创建了一个调用cache\u execute的函数,该函数允许我首先检查结果是否存在于缓存中,然后从缓存返回信息,如果信息尚未存在于缓存中,则从数据库返回信息(如果信息还不存在,则将其放入缓存) 下面是我当前代码的一个示例: namespace trf; class StatementWithCaching extends \PDOStatement { public $db; public $cache; pr
cache\u execute
的函数,该函数允许我首先检查结果是否存在于缓存中,然后从缓存返回信息,如果信息尚未存在于缓存中,则从数据库返回信息(如果信息还不存在,则将其放入缓存)
下面是我当前代码的一个示例:
namespace trf;
class StatementWithCaching extends \PDOStatement {
public $db;
public $cache;
protected function __construct(&$db) {
$this->db =& $db;
}
function cache_execute( $array = NULL , $cache = FALSE , $cacheTime = 1800 ) {
if( is_a( $cache , 'Memcache' ) ) {
$query = $this->queryString;
foreach ($array as $key => $value) {
$query = str_replace(':' . $key , "'" . addslashes( $value ) . "'", $query );
}
try {
$memResults = $this->mconn->get( md5( $this->queryString ) );
}
catch ( \Exception $e ) {
$memResults = FALSE;
}
} else {
}
}
}
我的问题是-如何将从缓存中检索到的信息放置在可由PDOStatement::fetch()
,PDOStatement::fetchAll()等检索到的位置
我的目标是能够运行语句WithCaching::execute()
或语句WithCaching::cache\u execute()
,并且仍然以相同的方式检索结果(使用语句WithCaching::fetch()
或语句WithCaching::fetchAll()
).我强烈建议您不要将缓存访问逻辑与DB访问逻辑混为一谈。换句话说,我不会尝试扩展DB特定的类来写入缓存。毕竟,当您不需要时,为什么要尝试将语句、结果集等概念引入简单的缓存层
相反,我将寻找更高级别的抽象,可能是一个类,您将向该类传递一个有效的DB连接和一个到缓存层的有效连接(在您的例子中是Memcache),并让该类协调读/写缓存和DB的逻辑
作为一个高级示例(显然这忽略了错误/异常处理等):
我能够通过扩展PDOStatement::fetch()
和PDOStatement::fetchAll()
函数来解决这个问题
namespace trf;
class StatementWithCaching extends \PDOStatement {
protected $db;
protected $cache;
protected $cacheReturn;
protected $cacheQuery;
protected $queryCacheTime;
protected function __construct(&$db) {
$this->db =& $db;
}
function cache_execute( $array = NULL , $cache = FALSE , $cacheTime = 1800 ) {
if( is_a( $cache , 'Memcache' ) ) {
$this->cache = $cache;
$this->queryCacheTime = $cacheTime;
$this->cacheQuery = $this->queryString;
if( $array !== NULL ) {
foreach ($array as $key => $value) {
$this->cacheQuery = str_replace(':' . $key , "'" . addslashes( $value ) . "'", $this->cacheQuery );
}
}
$this->debugData( 'Trying to get data from cache for query: ' . $this->cacheQuery . ' (' . md5( $this->cacheQuery ) . ')' );
$this->cacheQuery = md5( $this->cacheQuery );
try {
$this->cacheReturn = $this->cache->get( $this->cacheQuery );
$this->debugData( 'Reporting return: ' . var_export( $this->cacheReturn , TRUE ) );
}
catch ( \Exception $e ) {
$this->cacheReturn = FALSE;
$this->debugData( $e->getMessage() );
}
if( is_null( $this->cacheReturn ) || $this->cacheReturn == FALSE || is_null( $this->cacheQuery ) || !is_a( $this->cache , 'Memcache' ) ) {
if ($array === null) {
parent::execute();
} else {
parent::execute($array);
}
}
} else {
if ($array === null) {
parent::execute();
} else {
parent::execute($array);
}
}
}
function fetch( $fetchStyle = \PDO::FETCH_BOTH, $cursor_orientation = \PDO::FETCH_ORI_NEXT , $cursor_offset = 0 ) {
if( is_null( $this->cacheReturn ) || $this->cacheReturn == FALSE || is_null( $this->cacheQuery ) || !is_a( $this->cache , 'Memcache' ) ) {
$fullResults = parent::fetchAll();
if( is_a( $this->cache , 'Memcache' ) ) {
$this->debugData( 'Inserting data into cache:' . print_r( $fullResults , TRUE ) );
$this->cache->set($this->cacheQuery , $fullResults , MEMCACHE_COMPRESSED , $cacheTime );
}
return parent::fetch( $fetchStyle , $cursor_orientation = \PDO::FETCH_ORI_NEXT , $cursor_offset = 0 );
}
else {
$this->debugData( 'Returning Cached Results' );
switch ($fetchStyle) {
case \PDO::FETCH_BOTH:
return $this->cacheReturn[$cursor_offset];
break;
case \PDO::FETCH_ASSOC:
$data = $this->cacheReturn[$cursor_offset];
foreach ($data as $key => $value) {
if( is_numeric( $key ) ) {
unset( $data[$key] );
}
}
return $data;
break;
case \PDO::FETCH_LAZY:
$data = $this->cacheReturn[$cursor_offset];
$return = new \stdClass();
foreach ($data as $key => $value) {
if( !is_numeric( $key ) ) {
$return->$key = $value;
}
}
return $return;
break;
case \PDO::FETCH_OBJ:
$data = $this->cacheReturn[$cursor_offset];
$return = new \stdClass();
foreach ($data as $key => $value) {
if( !is_numeric( $key ) ) {
$return->$key = $value;
}
}
return $return;
break;
default:
return $this->cacheReturn[$cursor_offset];
break;
}
}
}
function fetchAll() {
if( is_null( $this->cacheReturn ) || $this->cacheReturn == FALSE || is_null( $this->cacheQuery ) || !is_a( $this->cache , 'Memcache' ) ) {
$fullResults = parent::fetchAll();
if( is_a( $this->cache , 'Memcache' ) ) {
$this->debugData( 'Inserting data into cache: ' . print_r( $fullResults , TRUE ) );
$this->cache->set($this->cacheQuery , $fullResults , MEMCACHE_COMPRESSED , $this->queryCacheTime );
}
return $fullResults;
} else {
$this->debugData( 'Returning Cached Results' );
return $this->cacheReturn;
}
}
private function debugData( $data ) {
if( isset( $_GET['debug'] ) && $_GET['debug'] = DEBUGVAL ) {
print('<pre>');
print_r( $data );
print('</pre>');
}
}
}
trf;
class语句WithCaching extends\PDO语句{
受保护$db;
受保护的$cache;
受保护的$cacheReturn;
受保护的$cacheQuery;
受保护的$queryCacheTime;
受保护的函数构造(&$db){
$this->db=&$db;
}
函数cache_execute($array=NULL,$cache=FALSE,$cacheTime=1800){
if(是($cache,'Memcache')){
$this->cache=$cache;
$this->queryCacheTime=$cacheTime;
$this->cacheQuery=$this->queryString;
如果($array!==NULL){
foreach($key=>$value的数组){
$this->cacheQuery=str_replace(':'.$key,''..addslashes($value)。“,$this->cacheQuery);
}
}
$this->debugData('Trying to get data from cache for query:'。$this->cacheQuery.'('.md5($this->cacheQuery)。'));
$this->cacheQuery=md5($this->cacheQuery);
试一试{
$this->cacheReturn=$this->cache->get($this->cacheQuery);
$this->debugData('Reporting return:'.var_export($this->cacheReturn,TRUE));
}
捕获(\异常$e){
$this->cacheReturn=FALSE;
$this->debugData($e->getMessage());
}
如果(is_null($this->cacheReturn)|$this->cacheReturn==FALSE | | is_null($this->cacheQuery)| |!is_a($this->cache,'Memcache')){
如果($array==null){
父::执行();
}否则{
父::执行($array);
}
}
}否则{
如果($array==null){
父::执行();
}否则{
父::执行($array);
}
}
}
函数fetch($fetchStyle=\PDO::fetch\u BOTH,$cursor\u orientation=\PDO::fetch\u ORI\u NEXT,$cursor\u offset=0){
如果(is_null($this->cacheReturn)|$this->cacheReturn==FALSE | | is_null($this->cacheQuery)| |!is_a($this->cache,'Memcache')){
$fullResults=parent::fetchAll();
如果(是a($this->cache,'Memcache')){
$this->debugData(‘将数据插入缓存:’。打印($fullResults,TRUE));
$this->cache->set($this->cacheQuery,$fullResults,MEMCACHE\u COMPRESSED,$cacheTime);
}
返回parent::fetch($fetchStyle,$cursor\u orientation=\PDO::fetch\u ORI\u NEXT,$cursor\u offset=0);
}
否则{
$this->debugData('Returning Cached Results');
开关($fetchStyle){
case\PDO::FETCH_两者:
return$this->cacheReturn[$cursor_offset];
打破
case\PDO::FETCH_ASSOC:
$data=$this->cacheReturn[$cursor_offset];
foreach($key=>$value形式的数据){
如果(是数字($key)){
未设置($data[$key]);
}
}
返回$data;
打破
case\PDO::FETCH_LAZY:
$data=$this->cacheReturn[$cursor_offset];
$return=new\stdClass();
foreach($key=>$value形式的数据){
如果(!是数字($key)){
$return->$key=$value;
}
}
return$return;
打破
case\PDO::FETCH_OBJ:
$data=$this->cacheReturn[$cursor_offset];
$return=new\stdClass();
foreach($key=>$value形式的数据){
如果(!是数字($key)){
$return->$key=$value;
}
}
return$return;
打破
违约:
return$this->cacheReturn[$cursor_offset];
打破
}
}
}
函数fetchA
namespace trf;
class StatementWithCaching extends \PDOStatement {
protected $db;
protected $cache;
protected $cacheReturn;
protected $cacheQuery;
protected $queryCacheTime;
protected function __construct(&$db) {
$this->db =& $db;
}
function cache_execute( $array = NULL , $cache = FALSE , $cacheTime = 1800 ) {
if( is_a( $cache , 'Memcache' ) ) {
$this->cache = $cache;
$this->queryCacheTime = $cacheTime;
$this->cacheQuery = $this->queryString;
if( $array !== NULL ) {
foreach ($array as $key => $value) {
$this->cacheQuery = str_replace(':' . $key , "'" . addslashes( $value ) . "'", $this->cacheQuery );
}
}
$this->debugData( 'Trying to get data from cache for query: ' . $this->cacheQuery . ' (' . md5( $this->cacheQuery ) . ')' );
$this->cacheQuery = md5( $this->cacheQuery );
try {
$this->cacheReturn = $this->cache->get( $this->cacheQuery );
$this->debugData( 'Reporting return: ' . var_export( $this->cacheReturn , TRUE ) );
}
catch ( \Exception $e ) {
$this->cacheReturn = FALSE;
$this->debugData( $e->getMessage() );
}
if( is_null( $this->cacheReturn ) || $this->cacheReturn == FALSE || is_null( $this->cacheQuery ) || !is_a( $this->cache , 'Memcache' ) ) {
if ($array === null) {
parent::execute();
} else {
parent::execute($array);
}
}
} else {
if ($array === null) {
parent::execute();
} else {
parent::execute($array);
}
}
}
function fetch( $fetchStyle = \PDO::FETCH_BOTH, $cursor_orientation = \PDO::FETCH_ORI_NEXT , $cursor_offset = 0 ) {
if( is_null( $this->cacheReturn ) || $this->cacheReturn == FALSE || is_null( $this->cacheQuery ) || !is_a( $this->cache , 'Memcache' ) ) {
$fullResults = parent::fetchAll();
if( is_a( $this->cache , 'Memcache' ) ) {
$this->debugData( 'Inserting data into cache:' . print_r( $fullResults , TRUE ) );
$this->cache->set($this->cacheQuery , $fullResults , MEMCACHE_COMPRESSED , $cacheTime );
}
return parent::fetch( $fetchStyle , $cursor_orientation = \PDO::FETCH_ORI_NEXT , $cursor_offset = 0 );
}
else {
$this->debugData( 'Returning Cached Results' );
switch ($fetchStyle) {
case \PDO::FETCH_BOTH:
return $this->cacheReturn[$cursor_offset];
break;
case \PDO::FETCH_ASSOC:
$data = $this->cacheReturn[$cursor_offset];
foreach ($data as $key => $value) {
if( is_numeric( $key ) ) {
unset( $data[$key] );
}
}
return $data;
break;
case \PDO::FETCH_LAZY:
$data = $this->cacheReturn[$cursor_offset];
$return = new \stdClass();
foreach ($data as $key => $value) {
if( !is_numeric( $key ) ) {
$return->$key = $value;
}
}
return $return;
break;
case \PDO::FETCH_OBJ:
$data = $this->cacheReturn[$cursor_offset];
$return = new \stdClass();
foreach ($data as $key => $value) {
if( !is_numeric( $key ) ) {
$return->$key = $value;
}
}
return $return;
break;
default:
return $this->cacheReturn[$cursor_offset];
break;
}
}
}
function fetchAll() {
if( is_null( $this->cacheReturn ) || $this->cacheReturn == FALSE || is_null( $this->cacheQuery ) || !is_a( $this->cache , 'Memcache' ) ) {
$fullResults = parent::fetchAll();
if( is_a( $this->cache , 'Memcache' ) ) {
$this->debugData( 'Inserting data into cache: ' . print_r( $fullResults , TRUE ) );
$this->cache->set($this->cacheQuery , $fullResults , MEMCACHE_COMPRESSED , $this->queryCacheTime );
}
return $fullResults;
} else {
$this->debugData( 'Returning Cached Results' );
return $this->cacheReturn;
}
}
private function debugData( $data ) {
if( isset( $_GET['debug'] ) && $_GET['debug'] = DEBUGVAL ) {
print('<pre>');
print_r( $data );
print('</pre>');
}
}
}