Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Вывод нескольких переменных из БД в Цикле
Форумы портала PHP.SU » » Вопросы новичков » Вывод нескольких переменных из БД в Цикле

Страниц (1): [1]
 

1. dnbdrive - 19 Декабря, 2011 - 22:32:17 - перейти к сообщению
Начал делать небольшой проект, при помощи книг и гугла справлялся, но в этот раз не приложу ума, что делать.
Говорю сразу - в php новичок, по этому в вопросе могу написать глупость.

Пусть в таблице "тт" есть 3 строки:
id - идентификатор проблемы
description - описание проблемы
equipments - идентификаторы оборудования, у которого есть проблемы (записывается как 1,33,43)

а в таблице equipments есть 2 строки:
id - идентификатор оборудования
name - название оборудования.

Допустим, я нахожусь на странице где выводится список ТТ, в каких то ТТ-шках указано одно оборудование, в каких то несколько, суть в том, чтобы вывести их название. Попробовал применить "foreach" в while, но последней ТТ был выведен список всего оборудования ...

Привожу кусок кода:

PHP:
скопировать код в буфер обмена
  1.  
  2.  
  3. $query = "SELECT * FROM problems LIMIT $start, $num_page";// Формируем запрос
  4. $result = mysql_query( $query );// Выполняем запрос
  5. if (!$result): die("Неудалось выполнить запрос<br /><h4>". mysql_error()) ."</h4>"; endif;
  6.  
  7. while ($row = mysql_fetch_array($result, MYSQL_ASSOC))  {
  8.  
  9. $id = $row["id"];
  10. $description = $row["description"];
  11.  
  12. // вот тут я хз, правильно или нет ...
  13.  
  14. if (empty($row["equipments"])) {
  15. $equipments = "железки не указаны";
  16. } else {       
  17. $equip = $row["equipments"];
  18. $parentsm = explode(",", $equip);
  19. foreach ( $parentsm as $element ) {
  20. $result2 = mysql_query( "SELECT `s_name` FROM  `equipments` WHERE  `id` = '$element' LIMIT 0 , 30") or die ("Ошибка запроса". mysql_error());
  21. if ($row_r = mysql_fetch_array($result2, MYSQL_ASSOC)): $equipments[] =  "<a href=\"/home.php?go=equipments&id=". $element ."\">". $row_r["name"] ."</a>"; endif;
  22. }
  23.                         $equipments = implode(', ', $equipments );
  24.                 }
  25.  
  26.  
  27. //вывожу все что вышло ...
  28.  
  29. echo <<<HTML
  30. Номер: $id | Описание: $description | Оборудование: $equipments
  31. HTML;
  32.  
  33.  


Если в таблице, например 5 записей, то в браузере вижу это:

Номер: 1 | Описание: описалово | Оборудование: сервер,
Номер: 2 | Описание: описалово | Оборудование: сервер, роутер,
Номер: 3 | Описание: описалово | Оборудование: сервер, роутер, коммутатор
Номер: 4 | Описание: описалово | Оборудование: сервер, роутер, коммутатор, cisco
Номер: 5 | Описание: описалово | Оборудование: сервер, роутер, коммутатор, cisco, dlink, магистраль

а должно быть так:
Номер: 1 | Описание: описалово | Оборудование: сервер,
Номер: 2 | Описание: описалово | Оборудование: роутер,
Номер: 3 | Описание: описалово | Оборудование: коммутатор
Номер: 4 | Описание: описалово | Оборудование: cisco
Номер: 5 | Описание: описалово | Оборудование: dlink, магистраль (этот пример с несколькими железками)

I need help!!! ...

По факту там все намного сложнее, но чтобы вы не вникали, упростил все как мог.
Благодарен за любую помощь!
2. tuareg - 19 Декабря, 2011 - 22:46:26 - перейти к сообщению
Если Вы еще далеко не ушли, есть возможность переделать БД, то надо это сделать.
Я бы сделал 3 таблицы(пишу по Вашим)
таблица тт:
id - идентификатор проблемы
description - описание проблемы

таблицу equipments: не трогать

И третья таблица(таблица связей)
id_tt-идентификатор проблемы(не автоинкремент!!!)
id_equipments -идентификаторы оборудования

И тут уже можно, как хочешь и что хочешь выводить.
3. dnbdrive - 19 Декабря, 2011 - 22:52:33 - перейти к сообщению
Спасибо за столь быстрый ответ, но как на зло уже достаточно далеко ушел Огорчение ( ...
а других способов никаких нет?

Подобный пример нашел в "не малоизвестном" движке DLE, вывод категорий (от туда я и применил этот способ) ... но как на зло не работает он нормально...
4. tuareg - 19 Декабря, 2011 - 23:06:35 - перейти к сообщению
Вы только зря MySQL "насилуете", все равно потом придется переделывать. Радость

По коду:
Вместо
PHP:
скопировать код в буфер обмена
  1.  
  2. $equip = $row["equipments"];
  3. $parentsm = explode(",", $equip);
  4. foreach ( $parentsm as $element ) {
  5. $result2 = mysql_query( "SELECT `s_name` FROM  `equipments` WHERE  `id` = '$element' LIMIT 0 , 30") or die ("Ошибка запроса". mysql_error());
  6.  


Сделайте так
PHP:
скопировать код в буфер обмена
  1.  
  2. $result2 = mysql_query( "SELECT `s_name` FROM  `equipments` WHERE  `id` IN(".$row["equipments"].")") or die ("Ошибка запроса". mysql_error());
  3.  

Так хоть будет один запрос в каждом цикле.
Потом снова while
PHP:
скопировать код в буфер обмена
  1.  
  2. while ($row2 = mysql_fetch_array($result2, MYSQL_ASSOC)){
  3.  тут собирайте их через запятую
  4. }
  5.  

Т.е логика следующая. Получили строку типа 1,2. Сделали запрос id IN(1,2)===>id=1 OR id=2
5. Okula - 19 Декабря, 2011 - 23:18:49 - перейти к сообщению
Вот я не понимаю людей которые пишут так

есть же функции mysql_fetch_assoc() или mysql_fetch_row() зачем забивать код лишним текстом, а вообще в mysql слишком много всего ненужного есть которое тянется со старых версий расширения, не пора ли отказаться от него?
6. dnbdrive - 20 Декабря, 2011 - 14:29:09 - перейти к сообщению
Okula пишет:
Вот я не понимаю людей которые пишут так

есть же функции mysql_fetch_assoc() или mysql_fetch_row() зачем забивать код лишним текстом, а вообще в mysql слишком много всего ненужного есть которое тянется со старых версий расширения, не пора ли отказаться от него?


Спасибо, буду знать. Я программирую только месяц, вот и туплю ...

tuareg пишет:
. Получили строку типа 1,2. Сделали запрос id IN(1,2)===>id=1 OR id=2


вот с этого момента поподробнее ...
Попробовал сделать так:

PHP:
скопировать код в буфер обмена
  1. $array = array($row["services"]);
  2. $service = implode(" тратата ", $array);
  3. echo $service;


и вместо 1 тратата 2 получаю 1,2

На этом вчера я завис, и вырубился ...
7. tuareg - 20 Декабря, 2011 - 14:39:42 - перейти к сообщению
Судя по Вашей схеме у Вас в поле equipments хранятся данные в следующем виде: 1,2,3?
И когда вы подставляете это в запрос получается следующее
PHP:
скопировать код в буфер обмена
  1.  
  2. /*Допустим $row["equipments"]='1,2,3'*/
  3. $result2 = mysql_query( "SELECT `s_name` FROM  `equipments` WHERE  `id` IN(".$row["equipments"].")");
  4. ===>
  5. $result2 = mysql_query( "SELECT `s_name` FROM  `equipments` WHERE  `id` IN(1,2,3)");
  6.  

А то что Вы указали это что такое? Откуда сие есть ???

P.S Лучше бы время на эту х... не теряли(ну не правильно это), а переделали БД. Я помогу с запросами

А я кажется понял Улыбка
Если $row["services"]='1,2,3';
PHP:
скопировать код в буфер обмена
  1.  
  2. $array = array($row["services"]);
  3. print_r($array);
  4. $array1 = array(1,2,3);
  5. print_r($array1);
  6.  

Выполните и посмотрите разницу.
8. dnbdrive - 20 Декабря, 2011 - 15:00:20 - перейти к сообщению
tuareg пишет:
P.S Лучше бы время на эту х... не теряли(ну не правильно это), а переделали БД. Я помогу с запросами


Только что думал об этом и поняв, как mysql сервер будет любить меня за это, решил все же переделывать это ...

В реале (это уже не пусть)

есть таблица Services — услуги, вот ее структура:

CODE (SQL):
скопировать код в буфер обмена
  1.   `id` int(11) NOT NULL AUTO_INCREMENT, -- уникальный идентификатор услуги
  2.   `s_name` varchar(100) NOT NULL DEFAULT '', -- короткое название услуги
  3.   `s_fullname` varchar(500) NOT NULL DEFAULT '', -- полное название услуги
  4.   `s_description` text NOT NULL, --  описание услуги
  5.   `s_tariff` varchar(200) NOT NULL DEFAULT '0', -- стоимость услуги (сохраняется id группы тарифов)
  6.   `s_tariffing` varchar(200) NOT NULL DEFAULT '0', -- тарификация услуги, где помесячная-1 или единоразовая-2
  7.   `s_info` text NOT NULL, -- информация об услуге
  8.   PRIMARY KEY (`id`)


Problems — список проблем

CODE (SQL):
скопировать код в буфер обмена
  1.   `id` int(11) NOT NULL AUTO_INCREMENT, -- уникальный идентификатор проблемы   
  2.   `date_reg` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -- дата регистрации (создания) проблемного билета
  3.   `date_start` varchar(20) NOT NULL DEFAULT '0', -- дата начала решения проблемы
  4.   `date_end` varchar(20) NOT NULL DEFAULT '0', --  дата решения проблемы
  5.   `responsible` mediumint(8) UNSIGNED NOT NULL DEFAULT '0', -- id ответственного за решение проблемы
  6.   `status` mediumint(8) UNSIGNED NOT NULL DEFAULT '0', -- статус проблемы
  7.   `priority` mediumint(8) UNSIGNED NOT NULL DEFAULT '0', -- приоритет проблемы
  8.   `services` varchar(200) NOT NULL DEFAULT '0', --  id услуг, на которые заведена проблема
  9.   `equipment` varchar(200) NOT NULL DEFAULT '0', -- id оборудования, но которые заведены проблемы
  10.   `description` text NOT NULL, --  подробное описание проблемы
  11.   `solution` text NOT NULL, -- способ решения проблемыы
  12. -- это можно пока не вносить, так как еще не придумал как и что будет записываться. ..
  13.   `log_id` mediumint(8) UNSIGNED NOT NULL DEFAULT '0', -- группа логов (тут я пока не решил, как логировать те или иные действия по "проблеме")
  14.   `log_rec` mediumint(8) UNSIGNED NOT NULL DEFAULT '0', --  id записи лога (тут я пока не решил, как логировать те или иные действия по "проблеме")
  15.   PRIMARY KEY (`id`),
  16. -- вот эти записи мне посоветовали сделать, но внятно так и не сказали зачем ...
  17.   KEY `responsible` (`responsible`),
  18.   KEY `services` (`services`),
  19.   KEY `equipment` (`equipment`),
  20.   KEY `log_id` (`log_id`),
  21.   KEY `log_rec` (`log_rec`)



Мега-благодарен за помощь !!!
9. tuareg - 20 Декабря, 2011 - 15:42:57 - перейти к сообщению
Тогда смотрите 1 таблица
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2.  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, -- уникальный идентификатор услуги
  3.   `s_name` varchar(100) NOT NULL DEFAULT '', -- короткое название услуги
  4.   `s_fullname` varchar(500) NOT NULL DEFAULT '', -- полное название услуги
  5.   `s_description` text NOT NULL, --  описание услуги
  6.   `s_tariff`int(11) UNSIGNED (можно сделать mediumint и т.д)  NOT NULL DEFAULT '0', -- стоимость услуги (сохраняется id группы тарифов)
  7.   `s_tariffing` ENUM('razovai','month') NOT NULL DEFAULT 'razovai', -- тарификация услуги, где помесячная-1 или единоразовая-2(аналог, только более понятный человеку)
  8.   `s_info` text NOT NULL, -- информация об услуге
  9.   PRIMARY KEY (`id`)
  10.  

вторая таблица
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. `id` int(11) NOT NULL AUTO_INCREMENT, -- уникальный идентификатор проблемы  
  3.   `date_reg` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, -- дата регистрации (создания) проблемного билета(при создании записи сам будет вставлять текущую дату и время)
  4.   `date_start` date NOT NULL DEFAULT '0000-00-00', -- дата начала решения проблемы
  5.   `date_end` date NOT NULL DEFAULT '0000-00-00', --  дата решения проблемы
  6.   `responsible` mediumint(8) UNSIGNED NOT NULL DEFAULT '0', -- id ответственного за решение проблемы
  7.   `status` mediumint(8) UNSIGNED NOT NULL DEFAULT '0', -- статус проблемы
  8.   `priority` mediumint(8) UNSIGNED NOT NULL DEFAULT '0', -- приоритет проблемы
  9.   `description` text NOT NULL, --  подробное описание проблемы
  10.   `solution` text NOT NULL, -- способ решения проблемыы
  11. PRIMARY KEY (`id`),
  12.  

3 таблица Связь между проблемами и услугами
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2.   id_prob int(11) UNSIGNED NOT NULL DEFAULT '0', -- идентификатор проблемы
  3.   id_usl int(11) UNSIGNED NOT NULL DEFAULT '0' -- идентификатор услуги
  4.  

Записываться будет так:
1 :1
1 :2
4 таблица Связь между проблемами и оборудованием
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2.   id_prob int(11) UNSIGNED NOT NULL DEFAULT '0', -- идентификатор проблемы
  3.   id_usl int(11) UNSIGNED NOT NULL DEFAULT '0' -- идентификатор оборудования
  4.  

Но это так вообще на вскидку. Все зависит, от Ваших требований(логики работы).
Что и как будет выдергиваться.
Ну на пример, во второй таблице оставить только описание и способ решения, а остальные данные вынести в еще одну таблицу и связать их по id, тут будет плюс если будут выборки по этим параметрам.(допустим по статусу проблемы или приоритету)
То что вам подсказали это индексы, но на данном этапе их делать нет смысла.
10. dnbdrive - 20 Декабря, 2011 - 16:09:01 - перейти к сообщению
tuareg пишет:
`date_reg` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, -- дата регистрации (создания) проблемного билета(при создании записи сам будет вставлять текущую дату и время)


То есть при создании записи, не нужно будет передавать текущую дату с помощью date()

tuareg пишет:
Ну на пример, во второй таблице оставить только описание и способ решения, а остальные данные вынести в еще одну таблицу и связать их по id, тут будет плюс если будут выборки по этим параметрам.(допустим по статусу проблемы или приоритету)


Я реализовал вывод проблем по статусу, с помощью swich и get, с этим вроде разобрался сразу, хотя возможно реализовать это еще проще, но не суть ...


по факту, на сколько я понял, для каждой связи нужно делать еще таблицу, или дотаточно одной таблицы, где будут все связи?

ну например пользователь:группа пользователя или клиент:услуга ...
(Добавление)
ну учитывая мое нынешнее состояние отложу "пищу для мозга" на завтра ...
11. tuareg - 20 Декабря, 2011 - 16:35:42 - перейти к сообщению
dnbdrive пишет:
То есть при создании записи, не нужно будет передавать текущую дату с помощью date()

да только время сервера MySQL.
dnbdrive пишет:
Я реализовал вывод проблем по статусу, с помощью swich и get...

Идея не в том как вы реализовали у себя. MySQL плохо работает с таблицами где есть поля типа TEXT. Выборка идет медленнее.

dnbdrive пишет:
для каждой связи нужно делать еще таблицу, или дотаточно одной таблицы, где будут все связи

Если их количество одинаковое, то можно одну.
В третью таблицу, можно добавить связь с ответственным за решение проблемы(если он один).
Вообще все зависит от Ваших выборок.
Допустим есть 2 таблицы
страны ==>id,name
города===>id,parent,name
Одним простым запросом оптимально не вытащить
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT t1.id,t1.name,t2.id,t2.name FROM страны AS t1 INNER JOIN города AS t2 ON t1.id=t2.parent WHERE t1.id='idстраны';
  3.  

Вот в этот запрос вернет
1 Россия 1 Новосибирск
1 Россия 2 Москва
...
1 Россия 50 Чита
Видно, что первые два столбика нужны только один раз, все остальное лишнее + объединение таблицы тоже не очень хорошо.
Я в таких случаях предпочитаю делать 2 простых запроса
1-запрос
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT id,name FROM страны  WHERE id='idстраны';
  3.  

2 запрос
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT id,name FROM города  WHERE parent='idстраны';
  3.  

А уже потом объединять рез-ты работая с массивом
P.S Вообще в идеале почитайте какую-нибудь книгу(статьи) про проектирование БД, благо их сейчас куча

P.S.S Так что-то конкретное советовать, не знаю логику работы Вашего приложения немного затруднительно

 

Powered by ExBB FM 1.0 RC1