PHP: 变量值神秘地设置为 0
PHP: variable value mysteriously set to 0
在此先感谢您的帮助!我遇到一种情况,我正在尝试调试一个变量神秘地设置为 0 的地方。
我从 xdebug(使用 PHPStorm)知道它发生在这个特定的行:
// breakpoint here: $id_key is 'my_entity_id_key'
$e_entity_ids = my_module_fetch_col_keyed($query, $id_key, $created_column);
// breakpoint here: $id_key is 0
很奇怪,因为$id_key
不是引用,函数也不把引用作为参数。此外,在值更改为 0
后,$id_key
在调试器的变量窗格中显示为蓝色。
我已经尝试制作变量的副本并使用它来传递给函数:
$id_key2 = $id_key;
$e_entity_ids = my_module_fetch_col_keyed($query, $id_key2, $created_column);
// breakpoint here: $id_key is 0, and so is $id_key2
我在想:
$id_key
的值怎么会神秘地变为 0?
- 如何创建
$id_key
的副本,以便在我将副本传递给 my_module_fetch_col_keyed()
时它不会被更改?
- 在 PHPStorm 的变量窗格中,变量名称显示为蓝色是什么意思?
当我进入my_module_fetch_col_keyed()
的时候,后面有一行$column神秘的是0
,如图:
function my_module_fetch_col_keyed($query, $column, $key_column = NULL) {
try {
$result = $query->execute();
}
catch (Exception $e) {
return FALSE;
}
if (!isset($key_column)) {
try {
// breakpoint here: $column is 'my_entity_id_key'
$column_results = $result->fetchCol($column);
// breakpoint here: $column is mysteriously 0
}
catch (Exception $e) {
return FALSE;
}
return $column_results;
}
try {
$assoc = $result->fetchAllAssoc($key_column);
}
catch (Exception $e) {
return FALSE;
}
$keyed = array();
foreach ($assoc as $key => $result) {
$keyed[$key] = $result->{$column};
}
return $keyed;
}
那个 $result->fetchCol()
函数只是一个调用 PDOStatement::fetchAll()
:
的函数
class DatabaseStatementBase extends PDOStatement implements DatabaseStatementInterface {
[...]
public function fetchCol($index = 0) {
return $this->fetchAll(PDO::FETCH_COLUMN, $index);
}
// function fetchAll() is not overridden from parent PDOStatement
[...]
}
编辑:我尝试将 $id_key
作为一个对象 属性 并使用神奇的 __set()
方法来获取回溯并找出变量的确切时间更改:
class Test {
private $id_key;
protected $values = array();
public function __set($key, $value) {
if ($key == 'id_key') {
$b = debug_backtrace();
"Hello World!";
}
if (method_exists(get_parent_class($this), '__set')) {
return parent::__set($key, $value);
}
return $this->values[$key] = $value;
}
public function __get($key) {
return isset($this->values[$key]) ? $this->values[$key] : 1;
}
}
然后我像这样更新了我的代码:
$e_entity_ids = basic_functions_fetch_col_keyed($query, $test->id_key, $created_column);
一切都像以前一样工作,$test->id_key
之前的计算结果为 my_entity_id_key
,之后的计算结果为 0
。我在 __set()
和 __get()
方法中设置了断点,并在调用它们时检查了值(例如,在上面的行中,在 basic_functions_fetch_col_keyed($query, $test->id_key, $created_column)
中调用了 get)。但是,奇怪的是,当值设置为 0
时, __set()
魔法函数没有被调用。我好迷路!任何帮助将不胜感激!
在我看来 id_key 确实是通过引用传递的。
其中一些 PDO 库是用 C 编码的。很可能在内部变量在那里被破坏。
TBF 您正在传递一个字符串作为需要数值的参数,因此从您使用的函数的角度来看,新值与旧值相同(大多数文本字符串不包含数字= 0).
在此先感谢您的帮助!我遇到一种情况,我正在尝试调试一个变量神秘地设置为 0 的地方。
我从 xdebug(使用 PHPStorm)知道它发生在这个特定的行:
// breakpoint here: $id_key is 'my_entity_id_key'
$e_entity_ids = my_module_fetch_col_keyed($query, $id_key, $created_column);
// breakpoint here: $id_key is 0
很奇怪,因为$id_key
不是引用,函数也不把引用作为参数。此外,在值更改为 0
后,$id_key
在调试器的变量窗格中显示为蓝色。
我已经尝试制作变量的副本并使用它来传递给函数:
$id_key2 = $id_key;
$e_entity_ids = my_module_fetch_col_keyed($query, $id_key2, $created_column);
// breakpoint here: $id_key is 0, and so is $id_key2
我在想:
$id_key
的值怎么会神秘地变为 0?- 如何创建
$id_key
的副本,以便在我将副本传递给my_module_fetch_col_keyed()
时它不会被更改? - 在 PHPStorm 的变量窗格中,变量名称显示为蓝色是什么意思?
当我进入my_module_fetch_col_keyed()
的时候,后面有一行$column神秘的是0
,如图:
function my_module_fetch_col_keyed($query, $column, $key_column = NULL) {
try {
$result = $query->execute();
}
catch (Exception $e) {
return FALSE;
}
if (!isset($key_column)) {
try {
// breakpoint here: $column is 'my_entity_id_key'
$column_results = $result->fetchCol($column);
// breakpoint here: $column is mysteriously 0
}
catch (Exception $e) {
return FALSE;
}
return $column_results;
}
try {
$assoc = $result->fetchAllAssoc($key_column);
}
catch (Exception $e) {
return FALSE;
}
$keyed = array();
foreach ($assoc as $key => $result) {
$keyed[$key] = $result->{$column};
}
return $keyed;
}
那个 $result->fetchCol()
函数只是一个调用 PDOStatement::fetchAll()
:
class DatabaseStatementBase extends PDOStatement implements DatabaseStatementInterface {
[...]
public function fetchCol($index = 0) {
return $this->fetchAll(PDO::FETCH_COLUMN, $index);
}
// function fetchAll() is not overridden from parent PDOStatement
[...]
}
编辑:我尝试将
$id_key
作为一个对象 属性 并使用神奇的 __set()
方法来获取回溯并找出变量的确切时间更改:
class Test {
private $id_key;
protected $values = array();
public function __set($key, $value) {
if ($key == 'id_key') {
$b = debug_backtrace();
"Hello World!";
}
if (method_exists(get_parent_class($this), '__set')) {
return parent::__set($key, $value);
}
return $this->values[$key] = $value;
}
public function __get($key) {
return isset($this->values[$key]) ? $this->values[$key] : 1;
}
}
然后我像这样更新了我的代码:
$e_entity_ids = basic_functions_fetch_col_keyed($query, $test->id_key, $created_column);
一切都像以前一样工作,$test->id_key
之前的计算结果为 my_entity_id_key
,之后的计算结果为 0
。我在 __set()
和 __get()
方法中设置了断点,并在调用它们时检查了值(例如,在上面的行中,在 basic_functions_fetch_col_keyed($query, $test->id_key, $created_column)
中调用了 get)。但是,奇怪的是,当值设置为 0
时, __set()
魔法函数没有被调用。我好迷路!任何帮助将不胜感激!
在我看来 id_key 确实是通过引用传递的。
其中一些 PDO 库是用 C 编码的。很可能在内部变量在那里被破坏。
TBF 您正在传递一个字符串作为需要数值的参数,因此从您使用的函数的角度来看,新值与旧值相同(大多数文本字符串不包含数字= 0).