在PHP中创建奇怪的数组?
我正在阅读mysqli_stmt_bind_的结果,并在以下文件中看到了此代码:在PHP中创建奇怪的数组?,php,arrays,variables,scope,php-5.3,mysqli,Php,Arrays,Variables,Scope,Php 5.3,Mysqli,我正在阅读mysqli_stmt_bind_的结果,并在以下文件中看到了此代码: 鉴于该行之前既不存在$params,也不存在$row,那么该行为什么/如何工作?来自第一条注释 $variables = array(); $data = array(); $meta = $result->result_metadata(); while($field = $meta->fetch_field()) $variables[] = &am
鉴于该行之前既不存在$params,也不存在$row,那么该行为什么/如何工作?来自第一条注释
$variables = array();
$data = array();
$meta = $result->result_metadata();
while($field = $meta->fetch_field())
$variables[] = &$data[$field->name]; // pass by reference
call_user_func_array(array($result, 'bind_result'), $variables);
那么问题出在哪里呢?它不起作用,因为正如你所说,这些变量不存在 PHP实际上没有变量声明。这意味着在某些情况下,您可以引用变量,而无需事先声明它们。我说有些情况是因为:
foreach($undefinedArray as $key=>$value){
// will give a notice and a warning
// notice: undefined variable
// warning: invalid argument to foreach
}
但这并不意味着你不能这样做:
for($i=0;$i<5;$i++){
$undefinedArray[]=$i;
}
// will create an array with 5 indexes, each holding the numbers 0 through 4
这就是魔法发生的地方,它实际上是由于&。因为和$row['unknown_index']
,实际上创建了该索引
这意味着上面的语句做了两件事。首先,它创建一个数组,每个列名保存为$row
($row[$field->name]
)中的索引。然后它保存一个指向$params
中$row
中每个元素的指针
call_user_func_array(array($stmt, 'bind_result'), $params);
这将$stmt->bind_result()
。但是将$params
中的每个元素作为参数传递给绑定结果。由于它们是通过引用传递的,$行的每个索引将保存每个选定字段
剩下的应该很容易弄清楚了
如果你有任何问题。请随便问从C、C++编程的角度来看,我有时很难理解PHP的堆栈和堆管理。PHP会自动处理太多的事情,这给了开发人员太多的自由。不管怎么说,我确信在他的精彩解释之后,他的疑虑已经消除了。我只想在代码中添加我的分钱,以便更清楚地了解所提到的代码中发生了什么 就这样。希望这段代码有意义 附言:作为事后思考,我想澄清我对PHP的一个疑问。如果我尝试填充$results,如下所示:
$results[$index][] = $row;
或者像这样:
$results[] = $row;
$results中的所有键/值对集合重复包含同一集合。希望有人能帮助我们了解PHP的这种行为
谢谢!但是作者为什么要在那里创建两个数组呢?仅仅做$row[$field->name]就足够了吗?(实际上我的意思是(不知道我可以直接链接到注释),但它们是相同的代码…)因为他想使用将数组的每个索引作为参数传递给函数的。通过该函数传递非固定数量的参数更容易,他还需要每个索引都是不会冲突的变量(即
$row
)。这个评论很难解释。如果你仍然不明白,我会重新考虑更新我的帖子:)是的,我明白为什么要使用call_user_func_array()。但是你所说的冲突是什么意思呢?我指的是变量的作用域,仅仅拥有$row[$field->name]
就可以与同一作用域中的其他变量发生冲突。对不起,我链接到了错误的手册页。链接现在已修复,您看到的评论是错误的。很抱歉,我一开始没有链接到它。在注释中,我的意思是$data在循环中调用之前不存在。
$stmt = $conn->prepare ("SELECT * FROM sample");
$stmt->execute ();
$meta = $stmt->result_metadata();
$params = array (); // You can skip these lines, PHP initiates arrays on
$row = array (); // the fly. I prefer doing as much of these initializations
$results = array (); // as possible, on my own.
while ($field = $meta->fetch_field())
{
/* Again, you can skip the following line, PHP will automatically create
* a new key/value pair and since we are using the same name for the
* container of that key/value pair, PHP will actually keep appending.
* So after N loops you have an array that contains N key/value pairs
*/
$row [$field->name] = 0;
$params[] =& $row[$field->name];
}
/* So now, $params is an array of N references, where reference i points to
* the value part of i-th key/val pair in $row
*/
call_user_func_array (array ($stmt, 'bind_result'), $params);
$index = 0;
while ($stmt->fetch ())
{
// again, one can skip this. PHP creates this on the fly.
$results[$index] = array();
foreach ($row as $key => $val)
{
// skip making that temp array!
$results[$index][$key] = $val;
}
$index += 1;
}
return $results;
$results[$index][] = $row;
$results[] = $row;