【问题标题】:PHP MYSQL - Populate HTML table numbered rows based on whether they match row numberPHP MYSQL - 根据是否匹配行号填充 HTML 表编号的行
【发布时间】:2012-11-02 01:17:43
【问题描述】:

所以,基本上我正在尝试制作数据中心驾驶室图。我们有一个 excel 电子表格,但这不容易更新,也不容易搜索。我在 MySQL 数据库中有三个表;数据库是:机架,表格是:机柜、设备和数据中心 - 每个表格中的每一行都代表它是什么。机柜表有一列指定它在 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', '', '', '');

【问题讨论】:

    标签: php html mysql sysadmin


    【解决方案1】:

    要直接解决问题(稍后我会介绍更多内容),您将遍历设备的完整列表,然后 - 在您完成所有设备的循环之后 -您尝试显示它们。因此,您只显示最后被触摸的设备。

    你当前的代码,被截断,是:

    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 是唯一的。

    旁注(附加的、非针对答案的批评)

    1. 在代码的开头,您执行$sql_devices="SELECT * FROMdevices";$result_devices=mysql_query($sql_devices);,但永远不要使用这个对象。它可以而且应该被删除,因为它是一个额外的(相当繁重的)查询。

    2. 在第二个while-loop 中,您有$num_devices=mysql_numrows($result_devices); 行。没有 PHP 函数 mysql_numrows(),我相信这是 mysql_num_rows() 函数的拼写错误(或者你有一个自定义编写的函数来做同样的事情。另外,$num_devices 变量从未使用过,所以这条线实际上可以完全删除。

    3. 1234563我和社区都建议您升级到mysqli_PDO 方法。
    4. 您的代码可能会出现未经处理的 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";

    【讨论】:

    • 谢谢,您的建议(我选择了更优雅的建议)奏效了。我非常感谢您的帮助和建议,并将检查并实施它们。我确实有一个后续问题:ustartlocation 指定设备可以启动的位置,因为有些设备可能跨越机柜中的多个 U。这将如何在 php 中处理(我在设备表中有 usize 字段)?我知道对于 html 表,它只是行跨度,但想知道 php 将如何处理它。
    • @eclipsed450 我很高兴它成功了!您的新/第二个问题值得在本网站上提出全新/其他问题。如果你用你现在工作的代码创建一个,链接我,我会看看我能不能帮忙(不过其他人可能会先得到它,这对你也一样好!)。
    猜你喜欢
    • 2012-10-24
    • 2021-08-10
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多