我们正在尝试将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"));
答案 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);
}
...
}