问题
Thanks in advance for your help! I have a situation I'm trying to debug where a variable is mysteriously set to 0.
I know from xdebug (using PHPStorm) that it happens at this specific line:
// 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
It's weird, because $id_key
is not a reference, nor does the function take a reference as a parameter. Also, after the value has changed to 0
, $id_key
is blue in the variables pane of the debugger.
I've tried making a copy of the variable and using it to pass to the function instead:
$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
I'm wondering:
- How could the value of
$id_key
be mysteriously changing to 0? - How can I create a copy of
$id_key
so that it's not changed when I pass the copy tomy_module_fetch_col_keyed()
? - What does it mean when a variable name is blue in the variables pane in PHPStorm?
When I step into my_module_fetch_col_keyed()
, there's a line after which $column is mysteriously 0
, as shown:
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;
}
and that $result->fetchCol()
function is just a one liner that calls 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
[...]
}
EDIT: I tried putting
$id_key
as an object property and using the magic __set()
method to get a backtrace and find out when exactly the variable is changed:
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;
}
}
and then I updated my code like so:
$e_entity_ids = basic_functions_fetch_col_keyed($query, $test->id_key, $created_column);
Everything keeps working the same way it was, and $test->id_key
evaluates to my_entity_id_key
before and 0
after. I set breakpoints with in the __set()
and __get()
methods, and examined the values when they were called (for example, in the above line the get is called in basic_functions_fetch_col_keyed($query, $test->id_key, $created_column)
). But, weirdly, THE __set()
MAGIC FUNCTION WAS NOT CALLED when the value was set to 0
. I'm so lost! Any help would be so appreciated!!
回答1:
It sure does look to me that id_key is being passed by reference.
Some of those PDO libraries are coded in C. It's quite possible that in the innards the variables get corrupted there.
TBF you're passing a string as an argument that expects a numeric value, so from the standpoint of the functions you're using, the new value is the same as the old value (most text strings not containing digits = 0).
来源:https://stackoverflow.com/questions/36730743/php-variable-value-mysteriously-set-to-0