У меня недавно была проблема (PHP: значение переменной таинственно установлено в 0) где переменная передавалась по значению в функцию PHP, и каким-то образом значение этой переменной было изменено, например, так:
$var = 'hello';
some_function($var);
echo $var; // outputs 0
Было выдвинуто предположение, что это старая функция, написанная на C, и во внутренней части она что-то делала, чтобы исказить переменную, поскольку в C, очевидно, вы можете делать такие вещи. В любом случае, я попытался сначала скопировать значение, а затем передать его следующим образом:
$var = 'hello';
$var2 = $var;
some_function($var2);
echo $var; // Still outputs 0
Конечно, это не помогло, потому что, когда я читал Вот PHP просто указывает $var2
в таблице символов к тому же контейнеру zval, что и $var
и увеличение рефконтаун этого zval контейнера. Конечно, если $var2
переназначается «по значению», для него должен быть создан новый контейнер zval, но это не было обычным присваиванием по значению, по-видимому (об этом было немного в предыдущем вопросе с __set()
волшебная вещь вещь). Я предположил, что что-то происходит с адресом физической памяти, по которому хранится значение, а не с присваиванием, выполняемым с помощью обычного механизма PHP, и, таким образом, все, что указывает на этот zval, будет затронуто. Отлично.
Мой обходной путь должен был найти способ клонировать примитив $var
, Извините, если это повторение, но я нашел тонны материала о клонировании классов, но ничего о клонировании примитивов, я думаю, потому что PHP должен делать это правильно автоматически. Я закончил тем, что использовал это:
$var = 'hello';
$serialized_var = serialize($var);
$var2 = unserialize($serialized_var);
some_function($var2);
echo $var; // Outputs 'hello', yay!
Мне просто интересно, есть ли лучший способ? Давайте предположим, что другого обходного пути нет, например, использование другой функции или чего-то еще, и что мы должны получить истинную копию переменной. Как можно это сделать?
Задача ещё не решена.
Других решений пока нет …