Значение не сохраняется в массиве

#php #mysql #arrays

#php #mysql #массивы

Вопрос:

У меня есть массив, который имеет такую структуру:

 $queues[n] Array (
[id] => integer
[idClient] => integer
[name] => string
[people] => integer )
  

Который заполняется:

 $query = "SELECT clients.idClient AS 'idClient', queues.idQueue AS 'idQueue', queues.name AS 'name' FROM clients, queues WHERE clients.idClient = queues.client";
    $queues = null;

    $result = mysql_query($query);
    if ($result){
        while ($queue = mysql_fetch_assoc($result)){
            $queues[] = array ("idClient" => $queue['idClient'], "id" => $queue['idQueue'], "name" => $queue['name'], "people" => 0);
        }
    }
  

Каждое значение ‘n’ соответствует очереди из базы данных и пользователей, по умолчанию установлено в 0.

После заполнения массива я снова запрашиваю базу данных с каждой очередью в другую таблицу, чтобы получить количество людей в очереди с помощью запроса, подобного этому:

 SELECT COUNT(*) FROM peoplequeued WHERE queue ='".$queue['name']."'
  

И затем:

 $result = mysql_query($query);
        if ($result){
            $num_people = mysql_fetch_row($result);
            $queue['people'] = $num_people[0];
        }
  

И здесь происходит что-то странное. Если я повторяю $queue [‘people’] в foreach, он отлично показывает полученное значение, но если я предварительно просмотрю весь массив перед его возвратом, он вернется к 0.

Что может происходить?

Комментарии:

1. Просто подсказка: если у вас неправильный код, не пишите здесь то, что вы считаете правильным кодом. Просто скопируйте / вставьте всю соответствующую последовательность. Могут быть ловушки, которые вы не заметили и не разместили их здесь. Другой совет: сделайте все это в одном запросе.

2. В качестве дополнительного примечания: я рекомендую изучить PDO и подготовленные инструкции. Помимо увеличения производительности, вы также значительно выиграете в безопасности. Показываемый вами запрос обычно доступен для SQL-инъекции.

3. Как вы получаете эту $queue переменную?

4. @AlexanderMP больше нет кода для вставки, только foreachs. @Arend этот код не может быть введен, поскольку вы в любом случае не можете изменить запрос.

5. @Antonio, это именно моя точка зрения. Эти foreach утверждения могут быть фактической причиной, но мы не можем определить это, потому что мы не можем их видеть. Вы признали, что в вашем коде была ошибка, но не позволили нам выяснить, где эта ошибка.

Ответ №1:

Я предполагаю, что вы выполняете цикл $queues с foreach помощью цикла, подобного этому:

 foreach ( $queues as $queue ) {
    $result = mysql_query($query);
    if ($result){
        $num_people = mysql_fetch_row($result);
        $queue['people'] = $num_people[0];
    }
}
  

Если это так, то между $queue и $queues[$n] нет «связи», т.е., изменяя $queue , вы НЕ изменяете $queues .

Если это так, вам следует либо использовать $queue в качестве ссылочной переменной, либо изменить, $queues[$n] используя $n значение индекса.

 foreach ( $queues as amp;$queue ) { // add amp; so $queue is a reference to an element in $queues
    $result = mysql_query($query);
    if ($result){
        $num_people = mysql_fetch_row($result);
        $queue['people'] = $num_people[0];
    }
}
unset($queue); // drop the reference, otherwise you might have unexpected results after modifying $queue outside the loop
  

… или …

 foreach ( $queues as $n => $queue ) { // store index of "current" element in $n
    $result = mysql_query($query);
    if ($result){
        $num_people = mysql_fetch_row($result);
        $queues[$n]['people'] = $num_people[0]; // change $queue to $queues[$n]
    }
}
  

В качестве альтернативы, я бы посоветовал вам подумать о получении всех данных в одном операторе. Похоже, что-то подобное может сработать для вас:

 select
    baseTable.id,
    baseTable.idClient,
    baseTable.name,
    peopleCount.count as people
from
    baseTable
    left join (
        select
            count(*) as count,
            queue
        from
            peoplequeued
        group by
            queue
    ) as peopleCount on peopleCount.queue = baseTable.name
  

Комментарии:

1. Большое спасибо за это, я думал, что они связаны, это не копия, а указатель. Спасибо: D

2. Они связаны, если вы добавляете amp; перед переменной. Но будьте осторожны с этим — переменная остается определенной и связанной с последним элементом массива, если вы не сделаете unset() этого после цикла. Кроме того, я обновил свой ответ альтернативным решением, которое позволило бы вам избавиться от нескольких запросов — выполнение запросов к БД в цикле — очень плохая практика.

3. Я должен попытаться адаптировать его, потому что он не работает с этой ошибкой: «У вас ошибка в вашем синтаксисе SQL; проверьте руководство, соответствующее вашей версии сервера MySQL, на предмет правильного синтаксиса для использования рядом с ‘LEFT JOIN (ВЫБЕРИТЕ COUNT(*) КАК ‘count’, cola Из relcolaext GROUP BY cola)» но спасибо за вашу помощь. Всегда полезно улучшать код и производительность.

4. Я создал baseTable таблицу, состоящую из id , idClient и name столбцов, и peoplequeued таблицу, состоящую из id полей queue , name и ,,. С такими таблицами этот запрос работает без какой-либо синтаксической ошибки. Если у вас есть where предложение, обязательно напишите его после объединения, т.е. select ... from some_source left join another_source where ... . Также я бы посоветовал изменить FROM clients, queues WHERE clients.idClient = queues.client part на join .

Ответ №2:

Похоже, вы, вероятно, используете foreach цикл для перебора вашего $queues массива, вот так:

 foreach($queues as $queue) {

}
  

Каждая сгенерированная $queue переменная является копией, и изменения в ней не сохраняются в $queues переменной. Чтобы сохранить изменения, как вы намереваетесь, вам нужно сделать что-то вроде:

 foreach($queues as $k => $queue) {
    $queue['people'] = 10;
    $queues[$k] = $queue;
    // or, more efficiently...
    $queues[$k]['people'] = 10;
}
  

В PHP5 вы также можете ссылаться. Смотрите http://uk.php.net/manual/en/control-structures.foreach.php

Комментарии:

1. Спасибо и за ваш ответ. Я не знал этого о PHP