PHP序列化替代方案

PHP序列化替代方案,php,optimization,serialization,Php,Optimization,Serialization,我正在为APC寻找一个好的缓存键,它表示关于一个对象的一些符合要求的信息,使用“对象”作为键。我有一个编译方法,它的功能如下: function compile(Obj $obj) { if ($this->cache) { $cachekey = serialize($obj); if ($data = $this->cache->get($obj)) { return $data

我正在为APC寻找一个好的缓存键,它表示关于一个对象的一些符合要求的信息,使用“对象”作为键。我有一个编译方法,它的功能如下:

function compile(Obj $obj)
{
    if ($this->cache)
    {
        $cachekey = serialize($obj);

        if ($data = $this->cache->get($obj))
        {
            return $data
        }
    }

    // compute result here

    if ($this->cache)
    {
        $this->cache->set($cachekey, $result);
    }

    return $result;
}
如果不明显,
$this->cache
是一个接口的实现,该接口具有
get
set
方法

除了创建此对象的某些属性所特有的密钥外,还有其他更快的方法吗?我可以提取出相关的位,但它们仍然是数组,这与我最初处理对象时遇到的序列化问题相同

序列化可以从“正确性”的角度工作,但它似乎是浪费(无论是在输出密钥的大小上,还是在计算复杂性上)

编辑:我还想补充一点,如果不是很明显,我将不需要取消序列化这个对象。我的当前缓存密钥的逐字代码实际上是:

$cachekey='compile'。sha1(序列化($obj))

编辑2:我正在使用的对象具有以下定义:

class Route
{
    protected $pattern;
    protected $defaults = array();
    protected $requirements = array();
}
Pattern
requirements
是将更改此方法输出的对象的值,因此这些值的散列必须出现在缓存键中

另外,有人建议使用uniqid(),这会破坏常规缓存查找键的用途,因为您无法从相同的信息可靠地重新生成相同的ID

编辑3:我想我没有给出足够的上下文。以下是到目前为止代码的链接:


我想我只是想避免昂贵的序列化调用(我想sha1也有点贵)。可能我能做的最好的事情就是尽量减少我序列化的内容的大小…

一种方法可能是仅根据用于计算结果的值生成一个键

下面是一个粗略的例子

function compile(Obj $obj)
{
    if ($this->cache)
    {
        $cachekey = 'Obj-result-' . sha1($obj->pattern . '-' . serialize($obj->requirements));
        // You could even try print_r($obj->requirements, true)
        // or even json_encode($obj->requirements)
        // or implode('-', $obj->requirements)
        // Can't say for sure which is slowest, or fastest.
        if ($data = $this->cache->get($cachekey))
        {
            return $data
        }
    }

    // compute result here
    $result = $obj->x + $obj->y; // irrelevant, and from original answer.

    if ($this->cache)
    {
        $this->cache->set($cachekey, $result);
    }

    return $result;
}

因为您使用的是一个数据数组,所以仍然需要将其转换为有意义的键。。然而,通过这种方式,您现在只序列化对象的一部分,而不是整个对象。看看进展如何。:)

实际上,在不知道整个系统如何工作的情况下,很难提出任何可行的解决方案


但是,为什么不在对象中添加一个带有
uniqid()
值的
cache\u key
属性呢?

我建议使用
函数,它似乎非常适合您的需要。

计算复杂性有什么问题吗?它运行的周期比我实际需要的要多;)当缓存命中时,serialize是当前唯一比apc_fetch本身花费更多时间的方法。因此,您要基于该数据项的值检索数据项,还是存储该数据项?这毫无意义-为了检索值,您必须已经知道它是什么!我正在对该项目进行额外处理。实际上,我正在为URL路由匹配器生成一个正则表达式,我想根据模式和正则表达式的要求来存储它,但在第一次需要它之前我不想生成。如果
Obj
有一个唯一的id,整件事不是会简单得多吗?但是$Obj->x和$Obj->y实际上是数组结构,这将需要序列化。。。。我将对对象结构进行编辑。在您的示例中,$pattern不是数组。不管怎样,我更新了我的答案。这是目前为止最好的解决方案~~我不明白随机的和不可复制的如何适应这种情况。有关该对象的详细信息,请参见上面的“我的编辑”。您没有正确理解我。我知道
uniqid()
是不可复制的。我的意思是用每个对象作为签名添加id。并将其用作对象的主键。您可以将其映射到相关对象,如[user1-obj12328018230]。很抱歉,您弄错了,如果您无法获取,请再次道歉。我现在就获取了,但我没有将对象存储在数据库中。检查“我的编辑”中的链接。此函数是否在请求之间保持一致的哈希?“一个字符串,对于当前存在的每个对象都是唯一的,对于每个对象总是相同的。”查看PHP手册页面上的注释。请注意,内容(属性)函数不会对对象的属性进行散列,只会对其内部句柄和处理程序表指针进行散列。”传入的每个请求在堆栈上可能有不同的起点。我正在打印其中一个对象的对象散列,它在每次请求时都会更改。这在请求之间不起作用。此外,当一个对象被销毁时,如果它随后在内存中占据相同的位置,则可以重新使用对象哈希。