我有一个包含捐赠者信息的数据库,然后有PHP页面来提取该数据并将其显示在捐赠者的特定类别下。 我使用的代码如下:
// 10,000 DONORS
echo "<p><b>$10,000 cont.</b></p>";
$sql = "SELECT * FROM donor WHERE DonationAmount = 10000 AND Category = '1' or DonationAmount = 10000 AND Category IS NULL ORDER BY LastName ASC LIMIT 10000 OFFSET 6";
$result = mysqli_query($conn, $sql);
$i = 0;
$total_rows = $result->num_rows;
echo "<table><tr>";
if (mysqli_num_rows($result) > 0) {
// output data of each row
while ($row = mysqli_fetch_assoc($result)) {
// test if the DisplayName field is empty or not
echo "<td>";
if (empty($row['DisplayName'])) {
// it's empty!
if (empty($row['FirstName'])) {
echo $row['LastName'];
}
else {
echo $row["LastName"] . ", " . $row["FirstName"];
}
} else {
// Do stuff with the field
echo $row["DisplayName"] . "";
}
echo "</td>";
$i++;
if ($i % 2 == 0 && $i != $total_rows) {
echo "</tr><tr>";
}
}
} else {
} echo "</tr></table>";
我的问题如下:现在名称以一种方式插入表中,使得读取左 - >右 - &gt;左 - >右等。我需要它们像普通列表一样显示从上到下工作并读取,并在被告知(计数器?)时滚动到下一列。我怎样才能做到这一点? Here is a preview off the page
编辑:试过这段代码:
$sql = "SELECT * FROM donor WHERE DonationAmount = 1000 AND Category = '1' or DonationAmount = 1000 AND Category IS NULL ORDER BY LastName ASC";
$result = mysqli_query($conn, $sql);
$i = 0;
$count = 0;
$total_rows = $result->num_rows;
$halfsize = $total_rows / 2;
$FirstArray = array();
$SecondArray = array();
while ($row = mysqli_fetch_assoc($result)){
while ($count <= $halfsize){
$FirstArray[] = $row['DisplayName'];
//echo "$FirstArray[$count]";
$count++;
}
$SecondArray[] = $row['DisplayName'];
//echo "$SecondArray[$count]";
}
echo "<table>";
for($j=0; $j<count($FirstArray); $j++){
echo "<tr><td>". $FirstArray[$j] . "</td><td>" . $SecondArray[$j] . "</td> </tr>";
}
echo "</table>";
我得到所有第一列(第一个数组?)的相同字段(第一个结果),然后第二个列(SecondArray)包含所有结果。
答案 0 :(得分:1)
我不会为此使用表格。可能还有其他一些css技巧。但是为了提问,我正在回答。
创建两个数组。
使用mysqli_num_rows获取结果集的大小,并将其除以2,然后遍历第一个数组并移动它们直到halfsize到array1。然后继续使用array2。
最后你会有类似的东西
Array 1 Array 2
------- -------
[0] Row 1 [0] Row 4
[1] Row 2 [1] Row 5
[2] Row 3
然后浏览它并填写你的html表。 (控制它们不要空着)
for($i=0; $i<count($array1); $i++){
echo '<tr><td>'.$array1[$i].'</td><td>'.$array2[$i].'</td></tr>';
}
答案 1 :(得分:1)
Your issue is not your PHP or your MySQL but your output handling.
So there's an array of data that's being dumped on your HTML and you need to order it to look nice . Two columns reading left to right in a table format.
The <table>
tag is perfect for this, and while most people hate the table tag, it is useful for tabled data.
It's worth noting that due to the flexibility and accommodating nature of CSS/HTML that this is not the only correct way but one of many ways this issue can be addressed
Method:
You have a while
loop outputting one unit at a time, a unit in this case being a name in a <td></td>
block. So that's your unit:
while {
print "unit";
}
So if you have two columns you want to arrange then you need to tell the while loop to distinguish between the first and the second column, this can be done with detecting if the counter (+1 for each itteration) is odd or even.
You can do this with the modulus divisor in PHP:
while {
counter++
if (counter%2) == 1 ){
//odd number.
}
}
So to sum it all up and give you a basic example:
$output = "";
$rowsTotal = mysqli_num_rows($result); //from your original code.
$counter = 0;
while ($row = mysqli_fetch_assoc($result)) {
$counter++; //plus 1 each itteration
if (($counter%2) == 1){
/// is odd so open the row of the table.
$output .= "<tr>";
}
$output .= "<td>";
if (empty($row['DisplayName'])) {
// it's empty!
if (empty($row['FirstName'])) {
$output .= $row['LastName'];
}
else {
$output .= $row["LastName"] . ", " . $row["FirstName"];
}
}
else {
// Do stuff with the field
$output .= $row["DisplayName"] . "";
}
$output .= "</td>";
if (($counter%2) == 0){
// if even so close the row of the table.
$output .= "</tr>";
}
// special case: If there area total of odd number of outputs
if($counter == $rowsTotal && $counter%2 == 1){
// so the last counter value is an odd number so force closure
// of </tr> (or add a blank space)
$output .= "<td> </td></tr>
}
} //end while.
...
print "<table>";
print $output;
print "</table>";
I don't want to dive deep into getting really creative with CSS but you can use CSS to finesse and improve the core HTML output setout above with some wonderful Cascading Style sheets, but above is a very rough outline of the sortof approach you could use to simulate a base level intelligence for the script to output names in the layout you are looking for.
Good luck.
CSS example:
table td {
background-color:#000;
color: #fff;
font-size:1.5rem;
text-align:left;
width:49%; /* 50% sometimes causes overflow, so set a tiny bit smaller */
padding:0.25rem;
margin:0;
box-sizing: border-box;
}
From comments, OP Needs the results from the SQL query to be two columns, rather than two rows. This means that table (a row structure) is inappropriate for this output and so instead we should use a more customised CSS / div tag set:
The layout would be two columns of approximatly 49% width each, and then each column contains block elements, This blob of blocks will then need to be split in half and a divider added to generate two shorter columns from one long one.
The block elements are output in a foreach loop and once the halfway point is met then an extra HTML code is inserted to break the elements up into a second <div>
. this is a little bit hacky it feel to me, but, does the job.
requirements:
A predefined counter of result rows. One can easily be generated. And that the SQL query is already ordered in the intended way, using MySQL ORDER BY
.
Semi-Pseudo code:
$array = SQL data result.
$counter = counter of how many array rows are returned.
$divisorCount = ceil($counter /2);
$foreachCount = 1
foreach ($array as $row){
$foreachCount++;
$block[] = "<div class='block'>".$row['data']."</div>\n";
if($foreachCount > $divisorCount){
$foreachCount = 0; //reset, as this will not be true again.
end($block);
$key = key($block); //most recent block array reference.
$block[$key] .= "</div><div class='column'>"; //the insert.
}
}
unset($row,$key,$foreachCount,$divisorCount); //tidyup.
The above generates a bunch of array elements, one for each name. There is an inserted splitter that ends the initial column and starts a second column, finally we wrap the whole block array into a final <div>
wrapper.
$output = "<div class='tableContainer'>
<div class='column'>".implode($block)."</div>
</div>";
The above output will be the opener for the first column but the closer for the second column. Within output we now have the complete columns for two columns of all results contained in a Div Container element.
The following CSS classes would need some tweaking to get right but should be a start:
CSS
.block{
line-height: 2rem;
display:block;
padding:0.25rem;
box-sizing:border-box;
}
.column{
width: 49%;
min-width:150px; /* or whatever. */
display:inline-block;
}
.tableContainer{
max-width: 800px; /* or whatever. */
min-width: 300px; /* or whatever. */
width:100%;
margin:auto; //centres it.
}
The CSS would be 49% rather than 50% because box sizes can have a tendancy to overflow on different browsers (Firefox especially), but the $output
would finally be:
HTML
<div class='tableContainer'>
<div class='column'><div class='block'>My Name</div>
<div class='block'>Your Name</div>
<div class='block'>His Name</div></div>
<div class='column'><div class='block'>Their Name</div>
<div class='block'>Her Name</div>
<div class='block'>Smacked HorseBombs</div>
</div>
</div>
You could also possibly substitute display:inline-block
for float:left
, but thats the basics, have a play on jsfiddle to tweak as you need.