PHP 中奇怪的数组创建?

发布于 2024-11-02 13:51:00 字数 424 浏览 2 评论 0原文

我正在阅读 mysqli_stmt_bind_result 的 PHP 手册 并看到此代码位于 注释

while ( $field = $meta->fetch_field() ) {
  $parameters[] = &$row[$field->name];
}

鉴于 $params 和 $row 都不存在于该行之前,为什么/该行如何工作?

I was reading the PHP manual for mysqli_stmt_bind_result and saw this code in the comments:

while ( $field = $meta->fetch_field() ) {
  $parameters[] = &$row[$field->name];
}

given that neither $params nor $row existed before that line, why/how does that line work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

め可乐爱微笑 2024-11-09 13:51:00

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

这是有效的,因为 $undefinedArray 不是即时找到和创建的。

现在,关于你自己的情况。我假设你的意思是这篇文章。我必须承认,这是一个非常有趣的解决方案,我会尽力克制自己不对任何不良做法发表评论,但让我们继续解释它!

$params[] = &$row[$field->name]; 

这就是神奇发生的地方,这实际上是由于 & 造成的。因为&$row['unknown_index'],实际上创建了索引!

这意味着上面的语句做了两件事。首先,它创建一个数组,其中每个列名称保存为 $row 中的索引($row[$field->name])。然后,它在 $params 中保存指向 $row 中每个元素的指针。

call_user_func_array(array($stmt, 'bind_result'), $params); 

这会执行$stmt->bind_result()。而是将 $params 中的每个元素作为参数传递给 bind_result。由于它们是通过引用传递的,因此 $row 的每个索引将保存每个选定的字段。

剩下的现在应该很容易弄清楚了。

如果您有任何疑问。欢迎询问!

PHP doesn't actually have variable declaration. That means in some cases you can reference variables without actually having them declared beforehand. I say some cases because:

foreach($undefinedArray as $key=>$value){
    // will give a notice and a warning
    // notice: undefined variable
    // warning: invalid argument to foreach
}

But this doesn't mean you can't do something like so:

for($i=0;$i<5;$i++){
    $undefinedArray[]=$i;
}
// will create an array with 5 indexes, each holding the numbers 0 through 4

This works because $undefinedArray is not found and created on the fly.

Now, regarding your own case. I'm gonna assume you mean this post. And I have to admit, that's a very interesting solution, I'm gonna try to restrain myself from commenting on any kind of bad practice there, but let's get on to explaining it!

$params[] = &$row[$field->name]; 

This is where the magic happens and it's actually due to the &. Because &$row['unknown_index'], actually creates the index!

This means that above statement does 2 things. First it creates an array with each column name saved as an index in $row ($row[$field->name]). Then it saves a pointer to each of the elements from $row in $params.

call_user_func_array(array($stmt, 'bind_result'), $params); 

This does $stmt->bind_result(). But passes each of the elements in $params as parameters to bind_result. And since they're passed by reference, each index of $row will hold each of the selected fields.

The rest should be easy to figure out now.

If you got any questions. Feel free to ask!

哆啦不做梦 2024-11-09 13:51:00

从第一条评论开始。

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

那么问题出在哪里呢?

From the first comment.

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

So what's the problem?

雪若未夕 2024-11-09 13:51:00

它不会起作用,因为正如你所说,这些变量不存在。

It won't work because as you said, these variables do not exist.

戏蝶舞 2024-11-09 13:51:00

来自 C、C++ 编程学校,我有时很难接受 PHP 的堆栈和堆管理。 PHP 自动完成太多的事情,这给了开发人员太多的自由。无论如何,我相信在 Dexter 的精彩解释之后,他的疑虑已经消除。 com/users/688411/khez">赫兹。我只是想在代码中添加我的美分,以便更好地理解提到的代码中发生的事情 此处

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

就是这样。希望这段代码有意义。

PS:事后想澄清一下我对PHP的一个疑惑。如果我尝试按如下方式填充 $results:

$results[$index][] = $row;

或者像这样:

$results[] = $row;

$results 中的所有键/值对集重复包含相同的集。希望有人能对 PHP 的这种行为有所启发。

Being from C,C++ school of programming, i sometimes struggle to come to terms with PHP's stack and heap management. PHP does way too many things automatically, which gives way too much freedom to developers. Anyways, am sure Dexter has got his doubts cleared after that wonderful explanation from Khez. I just want to add my cents in the code to make more sense of whats happening in the code mentioned here.

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

So that's it. Hopefully this code will make sense.

P.S: As an afterthought, I want to clarify one of my doubts regarding PHP. If I try to populate $results as below:

$results[$index][] = $row;

Or like this:

$results[] = $row;

All sets of key/value pairs in $results contain the same set repeatedly. Hopefully somebody and throw some light on this behavior of PHP.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文