PHP:变量值神秘地设置为0 [英] PHP: variable value mysteriously set to 0

查看:114
本文介绍了PHP:变量值神秘地设置为0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此先感谢您的帮助!我正在尝试调试将变量神秘地设置为0的情况.

Thanks in advance for your help! I have a situation I'm trying to debug where a variable is mysteriously set to 0.

我从xdebug(使用PHPStorm)知道它发生在以下特定行:

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

这很奇怪,因为$id_key不是引用,函数也不将引用作为参数.同样,在将值更改为0之后,$id_key在调试器的变量窗格中为蓝色.

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

我想知道:

  1. $id_key的值如何神秘地更改为0?
  2. 如何创建$id_key的副本,以便在将副本传递给my_module_fetch_col_keyed()时不被更改?
  3. 在PHPStorm的变量窗格中变量名称为蓝色时,这是什么意思?
  1. How could the value of $id_key be mysteriously changing to 0?
  2. How can I create a copy of $id_key so that it's not changed when I pass the copy to my_module_fetch_col_keyed()?
  3. What does it mean when a variable name is blue in the variables pane in PHPStorm?

当我进入my_module_fetch_col_keyed()时,在一行之后,$ column神秘地显示为0,如图所示:

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;
}

$result->fetchCol()函数只是一个调用PDOStatement::fetchAll()的衬里:

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

  [...]

}


编辑:我尝试将$id_key用作对象属性,并使用魔术的__set()方法获取回溯并查明何时准确更改了变量:


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);

所有内容均按以前的方式工作,并且$test->id_key之前的值为my_entity_id_key,之后的值为0.我在__set()__get()方法中设置了断点,并在调用它们时检查了这些值(例如,在上一行中,在basic_functions_fetch_col_keyed($query, $test->id_key, $created_column)中调用了get).但是,奇怪的是,将值设置为0时,没有调用__set()魔术功能.我很迷路!任何帮助将不胜感激!

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!!

推荐答案

在我看来,确实可以通过引用传递id_key.

It sure does look to me that id_key is being passed by reference.

其中一些PDO库是用C编写的.在内部,变量很可能在那里被破坏了.

Some of those PDO libraries are coded in C. It's quite possible that in the innards the variables get corrupted there.

TBF,您正在传递一个字符串作为需要数字值的参数,因此,从您使用的函数的角度来看,新值与旧值相同(大多数不包含数字= 0的文本字符串) ).

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

这篇关于PHP:变量值神秘地设置为0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆