Couchbase php / .Net客户端不兼容问题

时间:2013-10-18 19:03:34

标签: c# php memcached couchbase

我们正在尝试将couchbase客户端用于PHP和.NET。当我们用C#设置一个值然后用PHP读取它时,我们收到一个错误。 telneting到服务器时,我们没有任何问题走向另一个方向或读取值。有谁知道我们为什么会收到错误?

php'get'调用会导致以下错误:

警告:Couchbase :: get()[couchbase.get]:无法解压缩第5行的D:\ inetpub \ Webadvisor \ its \ test \ couchbase.php中的值(不良内容)

错误来自github上的php-ext-couchbase存储库中的couchbase.c。 https://github.com/couchbase/php-ext-couchbase/blob/master/convert.c#L213

C#代码:(这样可以正常工作)

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代码:

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

2 个答案:

答案 0 :(得分: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序列化器。

答案 1 :(得分: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 Transcoder(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);
    }
    ...
}