Есть вопрос по PHP (перебор значений массива)

Модератор: Модераторы разделов

Аватара пользователя
Dimon93rus
Сообщения: 428
Статус: Kernel Killer

Есть вопрос по PHP

Сообщение Dimon93rus »

Здравствуте. Немогу сформировать цикл для перебора всех значений массива, который получается в результате запроса.
Например получается ассоциативный массив который содержит следующие поля:
$arr["id_subject"] - id предмета;
$arr["id_group"] - id группы;
$arr["results"] - результаты;
Задача заключается в том, чтобы в таблице вывести $arr["id_subject"], $arr["id_group"] и общую сумму поля $arr["results"] для этих полей, т.е. где одинаковые значения поля $arr["id_subject"] и одинаковые значения поля $arr["id_group"].
+---------+------------+----------+
| results | id_subject | id_group |
+---------+------------+----------+
| 10 | 1 | 666 | (1)
| 12 | 1 | 666 | (2)
| 9 | 1 | 666 | (3)
| 11 | 1 | 666 | (4)
| 12 | 214 | 908745 | (5)
| 13 | 214 | 908745 | (6)
| 6 | 123 | 908745 | (7)
| 5 | 123 | 908745 | (8)
+---------+------------+----------+
Т.е. нужно подсчитать общую сумму для 1-4 строк, затем для 5-6, затем для 7-8.
У меня получается пока так, что сумма считается, но последняя строка не выводится. Подскажите как дописать.....

Код:

do { if ((empty($id_group)) and (empty($id_subject))) { $id_group = $ved["id_group"]; $id_subject = $ved["id_subject"]; $result = $ved["results"]; } else { if (($id_group == $ved["id_group"]) and ($id_subject == $ved["id_subject"])) { $result = $result + $ved["results"]; } else { echo "<tr><td>$id_group</td><td>$id_subject</td><td>$result</td></tr>"; $id_group = $ved["id_group"]; $id_subject = $ved["id_subject"]; $result = $ved["results"]; } } } while ($ved = mysql_fetch_array($ved_query));
Ubuntu Server 10.04 x86, Calculate Linux 11.6 x86
Спасибо сказали:
KernelPanic
Бывший модератор
Сообщения: 2060
Статус: Brain Атаке
ОС: Debian squeeze/sid/exp

Re: Есть вопрос по PHP

Сообщение KernelPanic »

Либо я туговат, либо ваш вопрос предназначен лишь для людей, которые делали нечто подобное и понимают вас с полуслова :)
Опишите проблему более понятливым языком, желательно, с примером того, что вы ожидаете получить.
Спасибо сказали:
Аватара пользователя
Voice
Сообщения: 1073
Статус: столлманист
ОС: Debian GNU/Linux

Re: Есть вопрос по PHP

Сообщение Voice »

А что если так:

Код: Выделить всё

<?php

$res = mysql_query("SELECT * FROM table_name");

$sum = array();
while($row = mysql_fetch_assoc($res)) {
    $key = $row['id_subject'] . "-" . $row['id_group'];

    if(isset($sum[$key]))
        $sum[$key] += $row['result'];
    else
        $sum[$key] = $row['result'];
}

print_r($sum);
?>
"И может собственных Платонов и быстрых разумом Невтонов российская земля рождать."
М. В. Ломоносов
Спасибо сказали:
Аватара пользователя
Dimon93rus
Сообщения: 428
Статус: Kernel Killer

Re: Есть вопрос по PHP

Сообщение Dimon93rus »

KernelPanic писал(а):
04.06.2008 18:44
Либо я туговат, либо ваш вопрос предназначен лишь для людей, которые делали нечто подобное и понимают вас с полуслова :)
Опишите проблему более понятливым языком, желательно, с примером того, что вы ожидаете получить.

Как ни странно, но я не удивлён что не очень понятно :)
Попробую расписать всё красивее.
На счёт полей массива я думаю понятно, да?
Допустим после запроса из БД получился массив который содержит следующие строки:
(строка - 1) id_group -> 666, id_subject -> 10 results -> 10
(строка - 2) id_group -> 666, id_subject -> 10 results -> 13
(строка - 3) id_group -> 666, id_subject -> 10 results -> 11
(строка - 4) id_group -> 666, id_subject -> 10 results -> 12
(строка - 5) id_group -> 111, id_subject -> 20 results -> 15
(строка - 6) id_group -> 111, id_subject -> 20 results -> 20
(строка - 7) id_group -> 222, id_subject -> 20 results -> 19
(строка - 8) id_group -> 333, id_subject -> 20 results -> 18
После этого мы начинаем построчно обрабатывать массив,
Берём первую строку и т.к. она первая присваиваем переменным соответствующие значения:
if ((empty($id_group)) and (empty($id_subject))) {
$id_group = $ved["id_group"];
$id_subject = $ved["id_subject"];
$result = $ved["results"];
}

Затем переходим ко второй строке и смотрим, если Id-группы и Id-предмета равны тем что были до этого, мы склдываем текущее значение поля results с предыдущим, и так далее, пока не поменяется Id-группы или Id-предмета, если мы узнаём, что они поменялись, то выводи строку таблицы такого вида:
Id группы | Id предмета | Общая сумма|
Теперь я думаю понятно что такое "Общая сумма", извиняюсь, просто не знал как правильнее сформировать это понятие. :)
В итоге у меня не получается вывести последнюю строку таблицы, т.к. цикл заканчивается.
Ну листинг кода я снва приводить не буду, Что я ещё непонятно описал?
Ubuntu Server 10.04 x86, Calculate Linux 11.6 x86
Спасибо сказали:
Аватара пользователя
Dimon93rus
Сообщения: 428
Статус: Kernel Killer

Re: Есть вопрос по PHP

Сообщение Dimon93rus »

2 Voice т.е. я так понимаю одним циклом мне это не реализовать? Ну да ладно :)
И, кстати:
$key = $row['id_subject'] . "-" . $row['id_group'];
Лучше, чтобы это присваивалось двум разным переменным:
$key1 = $row['id_subject'];
$key2 = $row['id_group'];
Соответственно и 2-м разным элементам массива.
Ubuntu Server 10.04 x86, Calculate Linux 11.6 x86
Спасибо сказали:
Аватара пользователя
Voice
Сообщения: 1073
Статус: столлманист
ОС: Debian GNU/Linux

Re: Есть вопрос по PHP

Сообщение Voice »

Dimon93rus писал(а):
04.06.2008 19:20
2 Voice т.е. я так понимаю одним циклом мне это не реализовать? Ну да ладно :)
И, кстати:
$key = $row['id_subject'] . "-" . $row['id_group'];
Лучше, чтобы это присваивалось двум разным переменным:
$key1 = $row['id_subject'];
$key2 = $row['id_group'];
Соответственно и 2-м разным элементам массива.

Нет, нет.

Значит идея следующая.
Проходим все строки результата последовательно. На каждом шаге плюсуем result к соответсвующему елементу масива сум
(если елемента пока нету то создаем).
А индекс того сомого елемента определяем как "id_subject-id_group" (тут не арифметическая операция, а строка).
Вы мой пример запутите, и после вывода print_r все поймете.

Потом результут можно обработать так:

Код: Выделить всё

<?
foreach($sum as $key => $val) {
        list($subject, $group) = split("-", $key);

        $val -- наша сума для данной групы строк
        $subject, $group -- соответсвенно параметры тех двох столбцов что пределили групу.
}
?>

Поняли идею?
"И может собственных Платонов и быстрых разумом Невтонов российская земля рождать."
М. В. Ломоносов
Спасибо сказали:
KernelPanic
Бывший модератор
Сообщения: 2060
Статус: Brain Атаке
ОС: Debian squeeze/sid/exp

Re: Есть вопрос по PHP

Сообщение KernelPanic »

Voice, насколько я понимаю, вы предлагаете сделать все через два цикла, 1 - для накопления данных в массиве $sum, 2- для их отображения (можно через foreach).
Однако, если данные больше нигде использоваться не будут, то это не есть рационально :).
Предлагаю такой вариант:

Код: Выделить всё

$output=0; //переменная, говорящая, что запрос не пустой и нужен вывод последней строки
while ($ved = mysql_fetch_assoc($ved_query))
{
    if ((empty($id_group)) and (empty($id_subject)))
    {
        $output = 1; //запрос не пустой и вывод будет
        $id_group = $ved["id_group"];
        $id_subject = $ved["id_subject"];
        $result = $ved["results"];
    }
    else if (($id_group == $ved["id_group"]) and ($id_subject == $ved["id_subject"]))
    {
        $result += $ved["results"];
    }
    else
    {
        echo "<tr><td>$id_group</td><td>$id_subject</td><td>$result</td></tr>";
        $id_group = $ved["id_group"];
        $id_subject = $ved["id_subject"];
        $result = $ved["results"];
    }
}

//Добавляем вывод для последней строки
if ($output) echo "<tr><td>$id_group</td><td>$id_subject</td><td>$result</td></tr>";
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: Есть вопрос по PHP

Сообщение Portnov »

Насколько я понял задачу, она решается средствами SQL. Смотрите в сторону предложения GROUP BY и функции SUM. Т.е. у вас будет запрос типа
SELECT id_subject, id_group, SUM(results) FROM my_table GROUP BY id_subject,id_group;
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
Аватара пользователя
sarutobi
Сообщения: 676
Статус: Добрость и скромнота
ОС: Debian 5, FreeBSD 6.2/8.0

Re: Есть вопрос по PHP

Сообщение sarutobi »

Dimon93rus
простите, а что именно мешает сделать запрос

Код: Выделить всё

select id_group, id_object, sum(result)  from table group by id_group, id_subject

или Вам нужно выводить итоговую строку после детализации?
Portnov +1
Fire and water, earth and sky - mistery surrounds us, legends never die!
Спасибо сказали:
Аватара пользователя
Dimon93rus
Сообщения: 428
Статус: Kernel Killer

Re: Есть вопрос по PHP

Сообщение Dimon93rus »

2 Voice да я всё прекрасно понял ещё с первого вашего поста :) За что Вам спасибо :).
Просто когда я сказал про второй цикл, то я имел в виду, вывод таблицы где каждая строка состоит из трёх ячеек: 1 - Id - группы, 2-я - id-предмета, 3-я результат. Поэтому мне нужно было чтобы $key не был один, я не много переделал, ваш скрипт, и у меня всё получилось как надо. НО.............
Portnov писал(а):
04.06.2008 22:10
Насколько я понял задачу, она решается средствами SQL. Смотрите в сторону предложения GROUP BY и функции SUM. Т.е. у вас будет запрос типа
SELECT id_subject, id_group, SUM(results) FROM my_table GROUP BY id_subject,id_group;

Этот вариант, на много проще... :)
Всем большое спасибо!!!!!!
Я думаю если в ближайшие неск. дней у меня вопросов не появится то тему можно будет закрыть.....

P.S. Пошёл учить SQL, может быть ещё отпадут лишние вопросы :)
Ubuntu Server 10.04 x86, Calculate Linux 11.6 x86
Спасибо сказали:
Аватара пользователя
Dimon93rus
Сообщения: 428
Статус: Kernel Killer

Re: Есть вопрос по PHP

Сообщение Dimon93rus »

Есть ещё вопрос:
Приведу простой пример.
Например есть каталоги: templates - шаблоны (например, содержит файл template.php), actions - с файлом action.php и в корне есть файл index.php и ещё несколько файлов.
Файл temlate.php вкладывается во все файлы, причём ссылки всегда отображаются с левой стороны от остального контента :)
Так вот, в template.php содержатся ссылки (не абсолютные) на файлы:
./actions/action.php
./index.php
./foo_file.php
Теперь распишу свои действия:
Теперь, допустим, изначально у меня открывается файл http://localhost/index.php,
Потом, я перехожу по ссылке http://localhost/foo_file.php
Потом по ссылке http://localhost/actions/action.php
А вот отсюда я уже не могу перейти никуда, т.к. ссылки не абсолютные и естественно, что файлов http://localhost/actions/index.php иhttp://localhost/actions/foo_file.php нет.
Так вот, собственно, в чём вопрос:
Как в шаблоне правильно прописывать эти ссылки, и чтобы они не являлись абсолютными?

Надеюсь я понятно описал проблему? :)
Ubuntu Server 10.04 x86, Calculate Linux 11.6 x86
Спасибо сказали:
Аватара пользователя
sh0ckfile
Сообщения: 168
Статус: Cirno fan
ОС: Ubuntu/WinXP

Re: Есть вопрос по PHP

Сообщение sh0ckfile »

Dimon93rus
Линки в хытымыеле не указывают на файлы относительно document_root - они показывают на файло относительно того, как файло отдаст вебсервер.
В вашем случае можно просто прописывать href="/index.php" или href="/action/action.php", разрулится.

Для ЧПУ (человеку-понятных-урлов) можно ещё заюзать mod_rewrite. Ну или не изобретать велосипедов...
"Чтобы быть человеком, нужно им какое-то время не быть" ©Ю.А.Бригадир
Registered Linux user #437143.
Спасибо сказали:
KernelPanic
Бывший модератор
Сообщения: 2060
Статус: Brain Атаке
ОС: Debian squeeze/sid/exp

Re: Есть вопрос по PHP

Сообщение KernelPanic »

Можно в начале каждого скрипта ввести переменную, которая "отслеживает" путь до корня сайта, потом эту переменную использовать для дописки левой части относительных урлов.
Т.е., в файле template.php ты будешь ссылки хранить относительно корня сайта:
$root_way."actions/action.php"
$root_way."index.php"
$root_way."foo_file.php
"

Где $root_way - это переменная пути до корня сайта.
Например в скрипте action.php переменная $root_way="../",
а для скриптов index.php и foo_file.php переменная $root_way="./".

Ну и в таком духе для всех скриптов.
Только переменную нужно определить до подключения template.php ;)
Спасибо сказали:
Аватара пользователя
destr
Сообщения: 128
ОС: Debian

Re: Есть вопрос по PHP

Сообщение destr »

Если я правильно понял, то используйте base href http://www.codenet.ru/webmast/web/gl_33.php
Спасибо сказали:
KernelPanic
Бывший модератор
Сообщения: 2060
Статус: Brain Атаке
ОС: Debian squeeze/sid/exp

Re: Есть вопрос по PHP

Сообщение KernelPanic »

Это неудобно и негибко, к тому же речь идет о пхп, зачем себя ограничивать?
Мой вариант можно использовать и не только в приведенном случае. Вообще, переменная $root_way - очень универсальна в применении, можно сказать, что ее применение ограничено только вашей фантазией.
- ее можно широко применять для "скинирования" сайта;
- для независимости урлов расположения библиотек функций от местоположения конечного скрипта в иерархии сайта.
И так далее, думайте сами. Это гибко и просто.
Спасибо сказали:
Аватара пользователя
Voice
Сообщения: 1073
Статус: столлманист
ОС: Debian GNU/Linux

Re: Есть вопрос по PHP

Сообщение Voice »

Обычно определяется константа корня сайта.
Например:
<? define('URL_ROOT', 'http://127.0.0.1/my_project'); ?>
А потом линки формировать относительно ее.
href="<?=URL_ROOT?>/foo/bar/file.php"

Так не будет проблем с переносом сайта.
"И может собственных Платонов и быстрых разумом Невтонов российская земля рождать."
М. В. Ломоносов
Спасибо сказали:
sim1
Сообщения: 155
ОС: GNU,BSD

Re: Есть вопрос по PHP

Сообщение sim1 »

Я так понял, что template.php это навигация поэтому для облегчения жизни советую не парится и использовать все-таки абсолютные ссылки типа:

/actions/action.php
/index.php
/foo_file.php

Ну или сделать, как предложил KernelPanic только оформить функцией, потом будет меньше гемороя

Код: Выделить всё

function printMenu( $a_Root ) {
   ....
   print "<a href='$a_Root/actions/action.php'>Actions</a>";
   ....
}
и звать из скриптов <?php printMenu("/"); ?>
Спасибо сказали:
KernelPanic
Бывший модератор
Сообщения: 2060
Статус: Brain Атаке
ОС: Debian squeeze/sid/exp

Re: Есть вопрос по PHP

Сообщение KernelPanic »

См. выше, никогда не будет проблем с переносом сайта :)
Спасибо сказали:
Аватара пользователя
Dimon93rus
Сообщения: 428
Статус: Kernel Killer

Re: Есть вопрос по PHP

Сообщение Dimon93rus »

Большое спасибо всем, попробую все варианты :)
Ubuntu Server 10.04 x86, Calculate Linux 11.6 x86
Спасибо сказали: