所以,基本上我想做一个数据中心出租车图。我们有一个excel电子表格,但这不容易更新,也不容易搜索。我在mysql数据库中有三个表;数据库是:机架,表是:机柜、设备和数据中心-每个表中的每一行都表示它是什么。cabinet表有一列指示它在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设备";$result_devices=mysql_query($sql_devices);,但从不使用此对象。它可以也应该被删除,因为它是一个额外的(相当重的)查询。
在第二个while-循环中有一行$num_devices=mysql_numrows($result_devices);。没有php函数mysql_numrows(),我认为这是mysql_num_rows()函数的一个错误(或者您有一个自定义编写的函数来执行相同的操作)。此外,从未使用过$num_devices变量,因此实际上可以完全删除这一行。
您正在使用旧的且已被弃用的mysql_函数(请查看这些函数的任何文档页面顶部的警告消息;这里有mysql_connect()可供参考)。我和社区都建议您升级到mysqli_PDO方法。
您的代码对未定义的sql错误是开放的,这并不仅仅限于sql注入,因为看起来您并没有直接从用户输入获取输入,但也不排除这个因素。例如,如果cabinetdatacenter值包含一个引号,会发生什么情况?由于您使用的是mysql_方法,我建议您在数据库调用中使用它们之前,先用mysql_real_escape_string()包装每个方法:$sql_cabinets="SELECT * FROM cabinets WHERE datacenter = '" . mysql_real_escape_string($datacenters_sqlrow[0]) . "' ORDER BY cabinetnumber";

09-25 16:43