Странное создание массива в PHP? - PullRequest
2 голосов
/ 22 апреля 2011

Я читал руководство по PHP для mysqli_stmt_bind_result и увидел этот код в комментариях :

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

учитывая, что до этой строки не было ни $ params, ни $ row, почему / как эта строка работает?

Ответы [ 4 ]

6 голосов
/ 22 апреля 2011

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'], на самом деле создает индекс!

Это означает, что вышеприведенное утверждение делает 2 вещи.Сначала он создает массив, имя каждого столбца которого сохраняется в виде индекса в $row ($row[$field->name]).Затем он сохраняет указатель на каждый из элементов из $row в $params.

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

Это делает $stmt->bind_result().Но передает каждый из элементов в $params в качестве параметров в bind_result.И так как они передаются по ссылке, каждый индекс $ row будет содержать каждое из выбранных полей.

Остальное должно быть легко выяснить сейчас.

Если у вас есть какие-либо вопросы.Не стесняйтесь спрашивать!

4 голосов
/ 22 апреля 2011

Из первого комментария.

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

Так в чем же проблема?

1 голос
/ 06 июня 2011

Будучи из школы программирования C, C ++, я иногда пытаюсь смириться с управлением стеком и кучей PHP.PHP делает слишком много вещей автоматически, что дает разработчикам слишком большую свободу.В любом случае, я уверен, что Декстер разрешил свои сомнения после того чудесного объяснения от Хез .Я просто хочу добавить свои центы в код, чтобы понять, что происходит в коде, упомянутом здесь .

$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[$index][] = $row;

Или так:

$results[] = $row;

Все наборы пар ключ / значение в $ results содержат один и тот же набор повторно.Надеюсь, кто-нибудь и пролить некоторый свет на это поведение PHP.

1 голос
/ 22 апреля 2011

Это не сработает, потому что, как вы сказали, эти переменные не существуют.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...