#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