Итак, в основном я пытаюсь сделать диаграмму кабины центра обработки данных. У нас есть таблица Excel, но это непросто обновить или легко найти. У меня три таблицы в базе данных MySQL; db: столы, таблицы: шкафы, устройства и датацентры – каждая строка в каждой из таблиц представляет, что это такое. Стол в шкафу имеет колонку, обозначающую, насколько высока она в U (некоторые шкафы в некоторых центрах обработки данных выше других). Итак, когда php рисует шкаф, он рисует шкаф на соответствующей высоте. До сих пор все работает в отношении группировки датацентров и их шкафов и их соответствующих высот. Моя проблема заключается в том, что я не могу заполнить более одного устройства в кабинете. Это целая страница, а настройка базы данных MySQL ниже:
<SCRIPT LANGUAGE="JavaScript" type="text/javascript"> <!-- function clickHandler(e) { var targetId, srcElement, targetElement; if (window.event) e = window.event; srcElement = e.srcElement? e.srcElement: e.target; if (srcElement.className == "Outline") { targetId = srcElement.id + "d"; targetElement = document.getElementById(targetId); if (targetElement.style.display == "none") { targetElement.style.display = ""; srcElement.src = "images/minus.gif"; } else { targetElement.style.display = "none"; srcElement.src = "images/plus.gif"; } } } document.onclick = clickHandler; --> </SCRIPT> <noscript>You need Javascript enabled for this page to work correctly</noscript> <? function sql_conn() { $username="root"; $password="root"; $database="racks"; $server="localhost"; @mysql_connect($server,$username,$password) or die("<h2 align=\"center\" class=\"red\">[<img src=\"images/critical.gif\" border=\"0\">] Unable to connect to $server [<img src=\"images/critical.gif\" border=\"0\">]</h2>"); @mysql_select_db($database) or die("<h2 align=\"center\" class=\"red\">[<img src=\"images/critical.gif\" border=\"0\">] Unable to select $database as a database [<img src=\"images/critical.gif\" border=\"0\">]</h2>"); } sql_conn(); $sql_datacenters="SELECT * FROM `datacenters`"; $sql_devices="SELECT * FROM `devices`"; $result_datacenters=mysql_query($sql_datacenters); $result_devices=mysql_query($sql_devices); $j=0; echo "<table border='1' style='float:left;'>"; while ($datacenters_sqlrow=mysql_fetch_array($result_datacenters)) { echo "<tr><td>"; echo "<h2 class='black' align='left'>"; echo "<IMG SRC='images/plus.gif' ID='Out" . $j . "' CLASS='Outline' STYLE='cursor:hand;cursor:pointer'>"; // fancy icon for expanding-collapsing section echo " " . $datacenters_sqlrow['rack'] . ": " . $datacenters_sqlrow['cagenum'] . "</h2>"; // datacenter name and cage number echo "<div id=\"Out" . $j . "d\" style=\"display:none\">"; // opening of div box for section that is to be expanded-collapsed echo "<h3>" . $datacenters_sqlrow['notes'] . "</h3>"; // datacenter notes $sql_cabinets="SELECT * FROM `cabinets` WHERE `datacenter` = '$datacenters_sqlrow[0]' ORDER BY `cabinetnumber` ASC"; $result_cabinets=mysql_query($sql_cabinets); while ($cabinets_sqlrow=mysql_fetch_array($result_cabinets)) { $sql_devices="SELECT * FROM `devices` WHERE `datacenter` = '$datacenters_sqlrow[0]' AND `cabinet` = '$cabinets_sqlrow[1]' ORDER BY `ustartlocation` ASC"; $result_devices=mysql_query($sql_devices); $num_devices=mysql_numrows($result_devices); echo "<table border='1' style='float:left;'>"; // opening of table for all cabinets in datacenter echo "<tr><td colspan='2' align='middle'>" . $cabinets_sqlrow[1] . "</td></tr>"; // cabinet number, spans U column and device name column while($row = mysql_fetch_array($result_devices)) { $server = $row['devicename']; $ustart = $row['ustartlocation']; } for ($i = 0; $i < $cabinets_sqlrow[2]; $i++) // iterates through number of U in cabinet { $u = $cabinets_sqlrow[2] - $i; // subtracts current $i value from number of U in cabinet since cabinets start their numbers from the bottom up echo "<tr>"; echo "<td width='15px' align='right'>$u</td>"; // U number echo "<td width='150px' align='middle'>"; if ($u == $ustart) // determines if there is a device starting at this U {echo $server;} // device name else {echo "empty";} // empty space in cabinet echo "</td>"; echo "</tr>"; } $server=""; $ustart=""; echo "</table>"; // closes table opened in row 65 } echo "</td></tr>"; echo "</div>"; // close for div box that needs expanding-collapsing by fancy java $j++; // iteration for the fancy java expand-collapse } echo "</table>"; mysql_close(); ?>
Вот настройка MySQL:
-- phpMyAdmin SQL Dump -- version 3.5.1 -- http://www.phpmyadmin.net -- -- Host: localhost -- Generation Time: Nov 02, 2012 at 02:13 AM -- Server version: 5.5.25 -- PHP Version: 5.4.4 SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; -- -- Database: `racks` -- -- -------------------------------------------------------- -- -- Table structure for table `cabinets` -- CREATE TABLE `cabinets` ( `id` tinyint(3) NOT NULL AUTO_INCREMENT, `cabinetnumber` varchar(25) NOT NULL, `numberofu` varchar(3) NOT NULL, `datacenter` tinyint(3) NOT NULL, KEY `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ; -- -- Dumping data for table `cabinets` -- INSERT INTO `cabinets` (`id`, `cabinetnumber`, `numberofu`, `datacenter`) VALUES (1, '0101', '45', 2), (2, '0102', '45', 2), (3, '0101', '50', 1), (4, '0102', '50', 1), (5, '0103', '50', 1); -- -------------------------------------------------------- -- -- Table structure for table `datacenters` -- CREATE TABLE `datacenters` ( `id` tinyint(3) NOT NULL AUTO_INCREMENT, `rack` varchar(20) NOT NULL, `cagenum` varchar(255) NOT NULL, `notes` longtext NOT NULL, KEY `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ; -- -- Dumping data for table `datacenters` -- INSERT INTO `datacenters` (`id`, `rack`, `cagenum`, `notes`) VALUES (1, 'CAGE1', '', ''), (2, 'CAGE2', '', ''), (3, 'CAGE3', '', ''), (4, 'CAGE4', '', ''), (5, 'CAGE5', '', ''), (6, 'CAGE6', '', ''), (7, 'CAGE7', '', ''); -- -------------------------------------------------------- -- -- Table structure for table `devices` -- CREATE TABLE `devices` ( `id` int(10) NOT NULL AUTO_INCREMENT, `devicename` varchar(255) NOT NULL, `datacenter` varchar(255) NOT NULL, `cabinet` varchar(255) NOT NULL, `frontorrear` tinyint(3) NOT NULL, `ustartlocation` varchar(255) NOT NULL, `usize` varchar(255) NOT NULL, `spare1` varchar(255) NOT NULL, `spare2` varchar(255) NOT NULL, `spare3` varchar(255) NOT NULL, KEY `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; -- -- Dumping data for table `devices` -- INSERT INTO `devices` (`id`, `devicename`, `datacenter`, `cabinet`, `frontorrear`, `ustartlocation`, `usize`, `spare1`, `spare2`, `spare3`) VALUES (1, 'SERVER1', '1', '0101', 1, '33', '1', '', '', ''), (2, 'SERVER2', '1', '0102', 1, '36', '1', '', '', ''), (3, 'SERVER3', '1', '0101', 1, '40', '2', '', '', '');
Чтобы напрямую решить проблему (я получу немного больше), вы выполняете итерацию через полный список устройств, а затем – после того, как вы завершите их все – вы пытаетесь их отобразить. Из-за этого вы показываете только последнее устройство, которое было затронуто.
Ваш текущий код, усеченный, следующий:
while($row = mysql_fetch_array($result_devices)) { $server = $row['devicename']; $ustart = $row['ustartlocation']; } for ($i = 0; $i < $cabinets_sqlrow[2]; $i++) { $u = $cabinets_sqlrow[2] - $i; ... if ($u == $ustart) { echo $server; } ... }
Если я понимаю, что вы пытаетесь сделать, вам нужно будет хранить каждое устройство в массиве «устройства» и прокручивать его во время каждой итерации цикла for
. Попробуйте что-нибудь вроде:
$devices = array(); while($row = mysql_fetch_array($result_devices)) { $devices[] = array( 'server' => $row['devicename'], 'ustart' => $row['ustartlocation'] ); } for ($i = 0; $i < $cabinets_sqlrow[2]; $i++) { ... $output = 'empty'; foreach ($devices as $device) { if ($u == $device['ustart']) { $output = $device['server']; break; } } echo $output; ... }
Более элегантный способ выполнения этой же задачи может быть выполнен с использованием ustartlocation
как индекса массива, но для этого потребуется, чтобы ustartlocation
был уникальным для отдельного устройства / сервера:
$devices = array(); while($row = mysql_fetch_array($result_devices)) { $devices[$row['ustartlocation']] = $row['devicename']; } for ($i = 0; $i < $cabinets_sqlrow[2]; $i++) { ... echo (isset($devices[$u]) ? $devices[$u] : 'empty'); ... }
Этот метод избавит вас от необходимости циклически перебирать список устройств каждый раз, но снова – для этого требуется, чтобы ustartlocation
был уникальным.
Боковые заметки (дополнительные критические замечания , не относящиеся к ответам)
В начале кода вы выполняете $sql_devices="SELECT * FROM
devices ";
и $result_devices=mysql_query($sql_devices);
, но никогда не используйте этот объект. Его можно и нужно удалить, поскольку это один дополнительный (довольно тяжелый) запрос.
Во втором while
-loop у вас есть строка $num_devices=mysql_numrows($result_devices);
, Нет PHP-функции mysql_numrows()
, я считаю, что это опечатка для функции mysql_num_rows()
(или у вас есть настраиваемая функция для выполнения той же самой вещи. Кроме того, переменная $num_devices
никогда не используется, поэтому это линия действительно может быть полностью удалена.
Вы используете старые и устаревшие функции mysql_
(проверьте это сообщение в верхней части любой из doc-страниц для этих функций, вот для mysql_connect()
для справки). Я, как и сообщество, рекомендую вам перейти на методы mysqli_
или PDO
.
Ваш код открыт для ошибок unsanitized-SQL, а не специально для SQL-инъекций, поскольку он не отображается, вы принимаете вход непосредственно с пользовательского ввода, но также не исключаете этот фактор. Например, что произойдет, если значение cabinet
или datacenter
содержать одну кавычку? Поскольку вы используете методы mysql_
, я предлагаю вам обернуть их с помощью mysql_real_escape_string()
до их использования в вызовах базы данных: $sql_cabinets="SELECT * FROM cabinets WHERE datacenter = '" . mysql_real_escape_string($datacenters_sqlrow[0]) . "' ORDER BY cabinetnumber";
$sql_cabinets="SELECT * FROM cabinets WHERE datacenter = '" . mysql_real_escape_string($datacenters_sqlrow[0]) . "' ORDER BY cabinetnumber";