【问题标题】:Memcache->get return different arrayMemcache->get 返回不同的数组
【发布时间】:2012-05-26 21:52:56
【问题描述】:

我做了这个功能: /* MEMCACHE */

function cache_query($sql,$nombre,$tiempo = -1){
    $cache = new Memcache();
    $cache->pconnect('localhost',11211);
    $query_cacheada = $cache->get($nombre);
    if ( $query_cacheada  === false ) {
             /* key not in memcache, perfom query, cache it and return */
         $res = mysql_query($sql);
         $cache->set($nombre,$res, 0, 60*60*24);  
         return $res; /* this looks good */
    }else{
             /* key in memcache, just return cached  */
         return $query_cacheada;  /* this doesnt return right elements */
    }
}

我就是这么用的:

class text{

    protected $id;
    protected $key;
    protected $language;
    protected $text;

    function __construct($clave,$lan){
       $consulta = cache_query("SELECT * FROM textos  
                                WHERE clave = '$clave' AND lengua = '$lan'" ,"TRANSLATION_".$clave."_".$lan);


        if(mysql_num_rows($consulta)>0){
            while($item = mysql_fetch_array($consulta)){
                $this->id = $item['id'];
                $this->clave = $item['key'];
                $this->lengua = $item['language'];
                $this->texto = $item['text'];

            }
                return true;
         }
    }
    function get_text(){
          return $this->text;
    }
}
function translation($key,$language){
     $tem = new text($key,$language);
     return $tem->get_text();
}

然后:

$translationText = translation('hello','fr');

问题是它存储在缓存数组中(总是零),var_dump($m->get(k)) 返回:

int(0) int(0) int(0) int(0) int(0) int(0) int(0) int(0) int(0) int(0) int(0) .....

并且$sql 查询很好因为行被很好地收集和打印,问题在于存储的值..

我已经清除了缓存(多次,以确保这些值不是来自以前的错误输出):

$consulta = $cache->get($nombre);
             /* manually*/
             $consulta = false;
        if ( $consulta === false) {
            $consulta = mysql_query($sql);
            $cache->set($nombre,$consulta, MEMCACHE_COMPRESSED, 60*60*24);
        };

所以..我错过了什么?

编辑

这是一个键盘,问题是 mysql_query 和 memecache 未启用,但以防有人想稍微摆弄一下

http://codepad.viper-7.com/PJNepH

【问题讨论】:

  • 传递$sql但使用$query,传递$tiempo但使用$iempo可以吗?
  • 是的。您想知道那个变量实际上是什么,不是吗?
  • 嘿!最后我看到了 var_dump: boolean(false) 所以它不是finidng它。还稍微编辑了函数@zerkms
  • 您为什么要尝试使用 memcache,而 MySQL query cache 应该对您的应用程序完全透明地完成这项工作?
  • @eggyal mysql 负载过多.. 我知道这不是正确的解决方法,但它会为我争取一些时间.. 我想知道如何做到这一点:)

标签: php mysql object memcached


【解决方案1】:

您只能缓存可以是serialized 的内容。这包括除resource 类型以外的所有内容(从成功的mysql_query 返回)。您需要稍微更改您的逻辑,以便缓存数组。改变这个:

$res = mysql_query($sql);
$cache->set($nombre,$res, 0, 60*60*24); 

收件人:

$res = mysql_query($sql);
$rows = array();
while($row = mysql_fetch_array($res)) $rows[] = $row;
$cache->set($nombre, $rows, 0, 60*60*24); 

然后改变这个:

if(mysql_num_rows($consulta)>0){
    while($item = mysql_fetch_array($consulta)){
        $this->id = $item['id'];
        $this->clave = $item['key'];
        $this->lengua = $item['language'];
        $this->texto = $item['text'];

    }
    return true;
}

收件人:

foreach($consulta as $item){
       $this->id = $item['id'];
       $this->clave = $item['key'];
       $this->lengua = $item['language'];
       $this->texto = $item['text'];
}

// This is your old code written to work with a 2D array instead of a resource,
// But this keeps overwriting the same variables in a loop,
// if you selected multiple rows; otherwise you don't even need a loop and can just do:

$this->id = $consulta[0]['id'];
$this->clave = $consulta[0]['key'];
$this->lengua = $consulta[0]['language'];
$this->texto = $consulta[0]['text'];

【讨论】:

    【解决方案2】:

    需要注意的重要一点是,您不能存储从mysql_query 返回的结果资源。我建议遍历结果集,使用mysql_fetch_array 获取它们,然后将这些对象存储在缓存中。

    编辑作为 PaulP.R.O.指出,显式序列化/反序列化是多余的。

    $result = mysql_query($sql) or die("Query failed");
    
    $results = array();
    
    while ($array = mysql_fetch_array($result))
    {
        $results[] = $array;
    }
    
    $cache->set($nombre, $results, MEMCACHE_COMPRESSED, 60*60*24);
    

    从 memcached 中检索时,只需使用未序列化的数组即可。

    $cachedItem = $cache->get($nombre);
    
    if ($cachedItem !== false) {
        var_dump($cachedItem);
    }
    

    【讨论】:

    • 调用serialize和unserialize是没有意义的,memcache已经对对象或数组自动完成了。
    • 嗨!感谢您的回答,但是在使用 mysq_fetch_object 时,它不会生成与 mysql_result 相同的数组,因此这些值没有很好地打印出来,并且没有很好地存储......知道为什么吗? (我返回 $results 因为 $result 在循环中已被清空)
    • @ToniMichelCaubet 您无法存储从 mysql_query 返回的内容。您只能存储使用从 mysql_query 返回的结果资源的函数返回的内容(例如 mysql_fetch_objectmysql_fetch_array)。 @PaulP.R.O 你是对的。我将删除显式的序列化/反序列化函数。
    • Paul 还重写了您的一些代码,因此如果我们不存储结果资源的原因不清楚,那么简单地尝试他的代码更改可能是值得的。
    【解决方案3】:

    Memcache 不接受超过 30 天的 TTL。您还可以使用 0 的 ttl 将密钥设置为永不过期,或者将 ttl 设置为小于 30 天。

    eliminating memcached's 30-day limit

    要创建一个易于序列化的变量,您可以执行以下操作。

    $consulta = mysql_query($sql);   
    while ($row = mysql_fetch_assoc($consulta)) {
      $data[] = $row;
    }
    $cache->set($nombre,$data, MEMCACHE_COMPRESSED, 60*60*24);
    

    【讨论】:

    • 编辑函数,现在它返回值!但由于某种原因,它存储了 mysql 结果,并且 var_dump 返回: int(0) int(0) int(0) int(0) int(0) int(0).... 任何想法? (在被缓存之前,它们按预期显示,所以 mysql 查询很好)
    • 好像在序列化mysql资源。通常,您要做的是将数据格式化为更容易序列化的格式,例如 PHP 数组,甚至 JSON,然后将其传递给 $cache->set。
    • 我看到了您的编辑。这将返回与缓存存储相同的内容...您不必初始化 $data 吗?我认为问题在于我的查询返回了一个对象数组...
    • 从语法的角度来看,在这种情况下,您实际上不必初始化 $data。由于这只是示例代码,我认为没有必要。但是,您应该初始化它,因为如果您不这样做,您将在$cache->set 行中收到一条 PHP 通知。你清除缓存了吗?
    • 我的意思是这个mysql_query类似于'select * from users where id=5'),所以它不包含值数组,而是对象。我这样做可以吗?
    猜你喜欢
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    相关资源
    最近更新 更多