0

We are trying to use the couchbase clients for PHP and .NET. We are getting an error when we set a value with C# then read it with PHP. We don't have any issues going the other direction or reading the values when telneting to the server. Does anyone know why we are getting an error?

The php 'get' call causes the following error:

Warning: Couchbase::get() [couchbase.get]: could not decompress value (bad content) in D:\inetpub\Webadvisor\its\test\couchbase.php on line 5

The error comes from couchbase.c in the php-ext-couchbase repository found on github. https://github.com/couchbase/php-ext-couchbase/blob/master/convert.c#L213

C# Code: (this works fine)

Couchbase.Configuration.CouchbaseClientConfiguration config = new Couchbase.Configuration.CouchbaseClientConfiguration();
config.Urls.Add(new Uri("http://127.0.0.1:8091/pools"));
CouchbaseClient client = new CouchbaseClient(config);
client.Store(StoreMode.Set, "foo", "bar");
client.Dispose();

PHP Code:

$cb = new Couchbase("127.0.0.1", "", "", "default");
var_dump($cb->get("foo"));
4

2 回答 2

0

事实证明,.NET 和 PHP 客户端不兼容的问题归结为客户端将 memcache 标志设置为什么。这些标志用于告诉客户端存储的值的类型。.NET 的标志基于 Type.GetTypeCode() 方法。因此,例如,当 .NET 客户端写入一个字符串进行缓存时,它会将标志设置为 274,但是 PHP 对 .NET 键入方案一无所知,也不知道如何处理该值,因此它尝试解压缩该值,这引发错误。当 PHP 将字符串写入缓存时,它会将标志设置为 0。

我们已经找到了针对该问题的两种不同的修复方法。第一个更多的是一种解决方法。如果将 PHP Couchbase 选项 COUCHBASE_OPT_IGNOREFLAGS 设置为 true,它将开始工作。

$cb = new Couchbase("127.0.0.1", "", "", "default");
$cb->setOption(COUCHBASE_OPT_IGNOREFLAGS,true);

我们最终采用的第二个解决方案是重载 .NET 转码器 (Enyim.Caching.Memcached.ITranscoder) 并设置标志以匹配 PHP 标志。

public class PHPTranscoder : ITranscoder
{
    ...
    public static uint TypeCodeToFlag(TypeCode code)
    {
        switch (code)
        {
            case TypeCode.String: return 0;
            case TypeCode.Int16: return 1;
            case TypeCode.Int32: return 1;
            case TypeCode.Int64: return 1;
            case TypeCode.UInt16: return 1;
            case TypeCode.UInt32: return 1;
            case TypeCode.UInt64: return 1;
            case TypeCode.Decimal: return 2;
            case TypeCode.Boolean: return 3;
            default: return 0; //default to string
        }

        // THE FOLLOWING IS COUCHBASE'S ORGINAL CODE
        // return (uint)((int)code | 0x0100);
    }
    ...
}
于 2013-10-21T16:34:45.987 回答
0

我认为这是因为 php 扩展php默认使用序列化程序来允许无缝序列化 PHP 中更广泛的对象。这是示例配置的摘录,解释了可用的选项:https ://github.com/couchbase/php-ext-couchbase/blob/master/example/couchbase.ini#L44-L52

; Specify the serializer to use to store objects in the Couchbase cluster.
;
; Legal values:
;   php        - Use the standard php serializer
;   json       - Use the php JSON encoding
;   json_array - Same as json, but decodes into arrays
;   igbinary   - This option is only available if the extension is build
;                with igbinary support
couchbase.serializer = php

在您的情况下,我认为您应该改用json序列化程序。

于 2013-10-21T10:37:07.063 回答