Кажущееся невозможным поведение ссылок на PHP-переменные при использовании метода set Memcached - PullRequest
3 голосов
/ 13 сентября 2010

У меня довольно странная проблема.Из-за определенной ошибки PECL я передаю переменную в 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) ""
*/

1 Ответ

1 голос
/ 13 сентября 2010

Если я правильно понимаю ошибку, проблема в том, что расширение memcache изменяет переданное значение напрямую, а не копирует перед выполнением изменений (т. Е. Оно не разделяет значение).

В этом случае это:

$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
...