3

つまり、基本的にはデータセンターのタクシー図を作成しようとしています。Excelスプレッドシートがありますが、これは更新も検索も簡単ではありません。MySQLDBに3つのテーブルがあります。dbはラック、テーブルはキャビネット、デバイス、データセンターです。各テーブルの各行は、それが何であるかを表します。キャビネットテーブルには、Uでの高さを示す列があります(一部のデータセンターの一部のキャビネットは、他のキャビネットよりも高さがあります)。したがって、phpがキャビネットを描画すると、それぞれの高さでキャビネットが描画されます。これまでのところ、データセンターとそれに含まれるキャビネットのグループ化、およびそれぞれの高さに関しては、すべてが機能します。私の問題は、キャビネットごとに複数のデバイスを配置できないように見えることです。これはページ全体であり、MySQLDBのセットアップはその下にあります。

<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', '', '', '');
4

1 に答える 1

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 * FROMコードの最初でデバイス";とを実行します$result_devices=mysql_query($sql_devices);が、このオブジェクトは使用しないでください。これは1つの余分な(かなり重い)クエリであるため、削除することができ、削除する必要があります。

  2. 2番目のwhileループには、行があります$num_devices=mysql_numrows($result_devices);。PHP関数はありませんmysql_numrows()。これは関数のタイプミスだとmysql_num_rows()思います(または、同じことを行うためのカスタム作成関数があります。また、$num_devices変数が使用されることはないため、この行は実際には完全に削除できます。

  3. 古くて廃止されmysql_た関数を使用しています(これらの関数のドキュメントページの上部にある警告メッセージを確認してくださいmysql_connect()。参照用にここにあります)。mysqli_私とコミュニティは、またはPDOメソッドにアップグレードすることをお勧めします。

  4. コードは、サニタイズされていない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";

于 2012-11-02T03:24:05.900 に答える