使用 Memcached 的 set 方法时看似不可能的 PHP 变量引用行为

发布于 2024-09-19 01:41:32 字数 1015 浏览 3 评论 0原文

我有一个相当奇怪的问题。由于 某些 PECL 错误,我将 var 传递到 memcached 并它会改变。建议的解决方法是传递 $data.'' 而不是 $data ,这会破坏引用。但这对我不起作用,因为我不只是将字符串传递到 memcached,我还传递所有数据类型。

因此,我最终分配了一个新变量,例如 $dataPass = $data 并传递 $dataPass。但真正奇怪的事情正在发生:

// ...

var_dump("data 1");
var_dump($data);

$dataPass = $data; // Dereferencing the variable 
                   // because of http://pecl.php.net/bugs/bug.php?id=14239

var_dump("data 2");
var_dump($data);
var_dump("dataPass 2");
var_dump($dataPass);

$this->memcache->set($key, $dataPass, false, time() + $expire);

var_dump("data 3");
var_dump($data);
var_dump("dataPass 3");
var_dump($dataPass);

/*
string(11) "data 1"
bool(false)
string(22) "data 2"
bool(false)
string(26) "dataPass 2"
bool(false)
string(10) "data 3"
string(0) ""                    <--- Why is this not bool(false)?
string(14) "dataPass 3"
string(0) ""
*/

I have a rather weird problem. Because of a certain PECL bug, I pass a var into memcached and it gets changed. The suggested workaround is to pass $data.'' instead of $data and that destroys the reference. But that won't work for me because I don't just pass strings into memcached, I pass all data types.

So I ended up assigning a new variable like $dataPass = $data and passing $dataPass. But something really weird is happening:

// ...

var_dump("data 1");
var_dump($data);

$dataPass = $data; // Dereferencing the variable 
                   // because of http://pecl.php.net/bugs/bug.php?id=14239

var_dump("data 2");
var_dump($data);
var_dump("dataPass 2");
var_dump($dataPass);

$this->memcache->set($key, $dataPass, false, time() + $expire);

var_dump("data 3");
var_dump($data);
var_dump("dataPass 3");
var_dump($dataPass);

/*
string(11) "data 1"
bool(false)
string(22) "data 2"
bool(false)
string(26) "dataPass 2"
bool(false)
string(10) "data 3"
string(0) ""                    <--- Why is this not bool(false)?
string(14) "dataPass 3"
string(0) ""
*/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

终难愈 2024-09-26 01:41:32

如果我正确理解该错误,问题在于内存缓存扩展直接修改传递的值,而不是在进行修改之前进行复制(即,它不分离值)。

,this:

$dataPass = $data;

在这种情况下,除了增加引用计数之外 绝对不执行任何操作。请参阅引用计数基础知识

强制分离的一种方法是创建一个参考集然后打破​​它:

$data = false; //$data's zval: refcount 1, is_ref 0
$dataPassPre =& $data; //$data/$dataPassPre zval: refcount 2, is_ref 1
//equivalently to below: $dataPass = $dataPassPre;
$dataPass = $data; //$dataPass's zval: has refcount 1, is_ref 0
unset($dataPassPre); //restore $data's zval to refcount 1, is_ref 0
//now pass $dataPass

If I understand the bug correctly, the problem is that the memcache extension modifies the passed value directly instead of copying before doing the modifications (i.e., it doesn't separate the value).

In that case, this:

$dataPass = $data;

does absolutely nothing besides incrementing the reference count. See reference counting basics.

One way to force the separation, would be to create a reference set and then break it:

$data = false; //$data's zval: refcount 1, is_ref 0
$dataPassPre =& $data; //$data/$dataPassPre zval: refcount 2, is_ref 1
//equivalently to below: $dataPass = $dataPassPre;
$dataPass = $data; //$dataPass's zval: has refcount 1, is_ref 0
unset($dataPassPre); //restore $data's zval to refcount 1, is_ref 0
//now pass $dataPass
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文