php memcached increment,PHP Memcached with Binary Protocol - 在increment()後返回垃圾數據

tl; dr;

這是PHP擴展代碼中的錯誤...

我挖成一個包裝libmemcached和libmemcached API代碼本身的PHP擴展的代碼,但我想我已經找到了你的問題可能的根本原因......

如果你看看PHP的Memcached::increment()實現你會看到line 1858 of php_memcached.c

status = memcached_increment_with_initial(m_obj->memc, key, key_len, (unsigned int)offset, initial, expiry, &value);

這裏的問題是,offset可能或不可能是64位寬。 libmemcached API告訴我們,memcached_increment_with_initial函數簽名期望uint64_t爲offset,而這裏offset被聲明爲long,然後轉換爲unsigned int。

所以,如果我們做這樣的事......

$memcached = new memcached;

$memcached->addServer('127.0.0.1','11211');

$memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, TRUE);

$memcached->delete('foo'); // remove the key if it already exists

$memcached->increment('foo',1,1);

var_dump($memcached->get('foo'));

你會看到類似...

string(22) "8589934592

"

從該腳本的輸出。 請注意,只有在密鑰foo尚未存在於該memcached服務器上時,此功能纔有效。還要注意在22個字符處的字符串的長度,當它明顯不應該在任何附近時。

如果你看一下該字符串的十六進制表示....

var_dump(bin2hex($memcached->get('foo')));

結果是清底垃圾...

string(44) "38353839393334353932000d0a000000000000000000"

正被存儲的目的是在劇組之間清楚地被破壞。因此,您最終可能會得到與我相同的結果,或者您最終可能會得到完全損壞的數據,如上所示。這取決於演員如何影響當時存儲的內存塊(這在這裏陷入未定義的行爲)。此外,唯一看似根本的原因是使用帶有增量的初始值(隨後使用increment,此後不會顯示該問題或密鑰是否已存在)。

我想這個問題不同於libmemcached API有memcached_increment和memcached_increment_with_initial

memcached_increment(memcached_st *ptr, const char *key, size_t key_length, uint32_t offset, uint64_t *value)

前者以uint32_t而後來發生uint64_t和PHP的擴展代碼之間的offset參數的兩個不同尺寸要求的事實莖投給unsigned int,這幾乎相當於uint32_t。

offset參數寬度上的這種差異很可能是導致密鑰在調用PHP擴展代碼和API代碼之間以某種方式被破壞的原因。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值