iT邦幫忙

2

php 再多層迴圈時 如何把值回傳出去?

  • 分享至 

  • xImage

php 再多層迴圈時 如何把值回傳出去?
有點太久沒碰 php 有點稍微忘記該怎麼寫了

目前的規劃是這樣的

echo '<table>';
$sql = "select * from tableA a";
while ($row_result = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    $aaa = $row_result['aaa'];
    $bbb = $row_result['bbb'];

    $sql = "select b.*,c.* from tableB b join tableC c on b.date = c.date where c.billNo='".$row_result['BillNo']."'";
    while ($row_result2 = mysqli_fetch_array($result2, MYSQLI_ASSOC)) {
        $ccc = $row_result['ccc'];
        $ddd = $row_result['ddd'];
        $eee = $row_result['eee'];
        $ctable='<tr>
            <td>$row_result['aaa']</td>
            <td>$row_result['bbb']</td>
            <td>$ccc</td>
            <td>$ddd</td>
            <td>$eee</td>
            </tr>';
    } 
    //total    
    if (mysqli_num_rows($result2) > 0) {
            $ctable='<tr>
            <td>$row_result['aaa']</td>
            <td>$row_result['bbb']</td>
            <td colspan="3">$ccc</td>
            </tr>';
    }
    $ctable='<tr>
            <td>$row_result['aaa']</td>
            <td>$row_result['bbb']</td>
            <td>$ccc</td>
            <td>$ddd</td>
            <td>$eee</td>
            </tr>'; 我在這裡要如何接到 $ccc,ddd,eee 動態的值?    
}

echo '</table>';

在畫表格的同時 我可以用 $row_result['aaa'] 去取得每一筆對應的值

但是當我要去得對應的 $ccc,$ddd,$eee 的值的時候 都確會是取得到最後一筆的資料

也就會導致 我的 $ccc,$ddd,$eee 的值都會是一樣的

這時我該如何做呢?

archer9080 iT邦研究生 3 級 ‧ 2021-08-19 16:07:42 檢舉
你這可能不只迴圈上的問題
而是整個php語法和邏輯都有問題...

(1).$result 和 $result_2你漏了,不過應該只是忘記打

(2).while ($row_result2 = mysqli_fetch_array($result2, MYSQLI_ASSOC))

if (mysqli_num_rows($result2) > 0)
意義是?

(3)$row_result['aaa'] 和 $ccc,$ddd,$eee的關聯是?
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
2
japhenchen
iT邦超人 1 級 ‧ 2021-08-19 14:41:50


echo $ctable ;啊....

不要在迴圈中邊轉邊echo
建議你把要組的table組好再一次echo
( php 組字串用 . )

$ctable = '<table>';
$sql = "select * from table a";
while ($row_result = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    $ctable .= '<tr>';
    $aaa = $row_result['aaa'];
    $bbb = $row_result['bbb'];

    $sql = "select * from table b";
    while ($row_result2 = mysqli_fetch_array($result2, MYSQLI_ASSOC)) {
        $ccc = $row_result['ccc'];
        $ctable .= '<td>$ccc</td>';
    } 
    $ctable .= '</tr>';
}
$ctable .='</table>';// 我在這裡要如何接到 $ccc 動態的值?    


echo $ctable ; 
看更多先前的回應...收起先前的回應...
ping1000 iT邦新手 5 級 ‧ 2021-08-19 14:58:24 檢舉

我更新內文了...剛剛好像遺漏了重點@@

你的SQL取值的方法真的很奇怪,我寫不對啦

table a跟 table b有何關聯?

你應該在SQL上下工夫,最好是以 join的方式關連兩個表,取值就不需要一再重新 SELECT

ping1000 iT邦新手 5 級 ‧ 2021-08-19 15:23:57 檢舉

沒辦法 join, 所以只這樣用

why not?

ping1000 iT邦新手 5 級 ‧ 2021-08-19 15:51:59 檢舉

我忘了更新SQL 語法了@@
已更新

不要在while裡再包一層SQL select !!
我不知你這個的用意,短埘間內一堆查詢,效能不會好,且你內層select只會不斷的從頭while到尾

aaa1 bbb1 ccc1 ccc2 ccc3 ccc3 ccc5 ........ ccc1000
aaa2 bbb2 ccc1 ccc2 ccc3 ccc4 ccc5 ........ ccc1000
aaa3 bbb3 ccc1 ccc2 ccc3 ccc4 ccc5 ........ ccc1000
aaa4 bbb4 ccc1 ccc2 ccc3 ccc4 ccc5 ........ ccc1000
aaa5 bbb5 ccc1 ccc2 ccc3 ccc4 ccc5 ........ ccc1000
aaa6 bbb6 ccc1 ccc2 ccc3 ccc4 ccc5 ........ ccc1000
.............

你的心思 https://ithelp.ithome.com.tw/upload/images/20210820/20117954oFm0FBD8lS.jpg

fillano iT邦超人 1 級 ‧ 2021-08-25 06:35:48 檢舉

看起來他如果多做一次join,一個查詢就可以解決的...把查詢這樣包進while裡面會數量級地變慢XD

1
firecold
iT邦新手 1 級 ‧ 2021-08-19 14:48:07

把資料整理出來在用for吧
另外要不要考慮用pdo?
兩維也可以先整理

$ccc = [];

$sql = "select * from table a";
while ($row_result = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    $aaa = $row_result['aaa'];
    $bbb = $row_result['bbb'];

    $sql = "select * from table b";
    while ($row_result2 = mysqli_fetch_array($result2, MYSQLI_ASSOC)) {
        $ccc[] = $row_result['ccc'];
    } 
}

for($c = 0; $c < count($ccc); $c++){
   $ctable='<table><tr><td></td></tr></table>';// 我在這裡要如何接到 $ccc 動態的值?    
}
看更多先前的回應...收起先前的回應...
ping1000 iT邦新手 5 級 ‧ 2021-08-19 15:01:05 檢舉

我更新內文了...剛剛好像遺漏了重點@@
pdo方式的話... 我忘了怎麼用= ="
pdo 的話 是改成 foreach?

firecold iT邦新手 1 級 ‧ 2021-08-19 15:07:40 檢舉

先不管pdo
你$ccc會是最後一筆是因為每個迴圈都會複寫變數
你把它存成陣列
外部在調用就可以了

ping1000 iT邦新手 5 級 ‧ 2021-08-19 15:27:03 檢舉

可是會出現陣列錯誤@@
count(): Parameter must be an array or an object that implements Countable

$ccc[] = $row_result['ccc'];

}

$ctable='<tr>
            <td>$row_result['aaa']</td>
            <td>$row_result['bbb']</td>';
            for($c = 0; $c < count($ccc); $c++){
                <td>$ccc</td>;
            }
            '<td>$ddd</td>
            <td>$eee</td>
            </tr>';
firecold iT邦新手 1 級 ‧ 2021-08-19 15:56:53 檢舉

$ccc[] = $row_result['ccc'];
要寫在迴圈裡面
for裡面
要寫$ccc[$c]

firecold iT邦新手 1 級 ‧ 2021-08-19 15:57:35 檢舉

對結構不熟悉
先var_dump一步一步看卡在哪裡

ping1000 iT邦新手 5 級 ‧ 2021-08-19 17:30:08 檢舉

我檢查了一下 應該是在進入第二層迴圈時 可能某些表單是沒有資料的
所以會出現錯誤

可是我下 if(!$row_result) 也還是一樣是錯誤= =

1
Hankz
iT邦新手 2 級 ‧ 2021-08-19 14:48:28

我猜你是想要這樣:

$sql = "select * from table a";
$ctable='<table>';
while ($row_result = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    $ctable .= '<tr>';
    $aaa = $row_result['aaa'];
    $bbb = $row_result['bbb'];

    $sql = "select * from table b";
    while ($row_result2 = mysqli_fetch_array($result2, MYSQLI_ASSOC)) {
        $ccc = $row_result['ccc'];
        $ctable .= '<td>' . $aaa . '</td>';
        $ctable .= '<td>' . $bbb . '</td>';
        $ctable .= '<td>' . $ccc . '</td>';        
    } 
    $ctable .= '</tr>';
}
$ctable .= '</table>';
echo $ctable;

結果:

aaa bbb ccc
a1 b1 c1
a1 b1 c2
a2 b2 c1
a2 b2 c2
ac bc c1
看更多先前的回應...收起先前的回應...
ping1000 iT邦新手 5 級 ‧ 2021-08-19 14:58:02 檢舉

我更新內文了...剛剛好像遺漏了重點@@

Hankz iT邦新手 2 級 ‧ 2021-08-19 15:34:05 檢舉

更新完之後反而看不懂了...

你要不要把你的目的、最後想要呈現的樣子
用個範例表格寫一下啊
就像我上面的表格一樣

不知道你到底想要呈現的結果
不知道為什麼要在迴圈裡面一直下相同的sql
不知道明明取得table b了的資料,但卻一直在迴圈外處理(所以當然只有最後一筆)
是每次的結果都不一樣嗎? 那就在第二層迴圈串字串或是用join一次跑完
如果結果都一樣,那為甚麼不在外面跑完、再前處理後,存成陣列到迴圈裡面指定key值取回資料呢?

我覺得你需要先把問題描述清楚,我們才有辦法幫你

ping1000 iT邦新手 5 級 ‧ 2021-08-19 15:50:53 檢舉

我忘了更新 SQL 語法@@
因為第二層 無法跟第一層串起來 所以要額用外 才可以
已更新 SQL 語法

Hankz iT邦新手 2 級 ‧ 2021-08-19 16:18:06 檢舉

單看語法應該是能串起來的...但這先不管

$aaa = $row_result['aaa'];
$bbb = $row_result['bbb'];

$sql = "select b.*,c.* from tableB b join tableC c on b.date = c.date where c.billNo='".$row_result['BillNo']."'";
while ($row_result2 = mysqli_fetch_array($result2, MYSQLI_ASSOC)) {
    $ccc = $row_result['ccc'];
    $ddd = $row_result['ddd'];
    $eee = $row_result['eee'];
    $ctable="<tr>" +
        "<td>$aaa</td>" +
        "<td>$bbb</td>" +
        "<td>$ccc</td>" +
        "<td>$ddd</td>" +
        "<td>$eee</td>" + //這裡不就取到了嗎?
        "</tr>";
} 
//total    
if (mysqli_num_rows($result2) > 0) {
    // 這個if看不懂目的
    $ctable="<tr>" +
        "<td>$aaa</td>" +
        "<td>$bbb</td>" +
        "<td>$ccc</td>" +
        "<td>$ddd</td>" +
        "<td>$eee</td>" + 
        "</tr>";
}
$ctable="<tr>" +
    "<td>$aaa</td>" +
    "<td>$bbb</td>" +
    "<td>$ccc</td>" +
    "<td>$ddd</td>" +
    "<td>$eee</td>" + //都出迴圈了怎麼取
    "</tr>";

所以到底為甚麼要一直在$result2外面處理...
如果這也不是你要的 那就先試著把你要呈現的結果描述一下吧
而不是看誰先通靈 猜到你要什麼

還有 那些語法錯誤有時間整理一下...

ping1000 iT邦新手 5 級 ‧ 2021-08-19 17:25:00 檢舉

因為要把 $result2 的值 放去最外層的那個 td 才可以啊...我也不想這樣弄=___=

因為在 while ($row_result2) 在這一層的 while 是畫本身 result2 的迴圈取得東西的 td

假如 result 的總數 大於 2 的畫 會在 if 判斷那邊去合併一些 td

然後離開 result2 的迴圈之後 才會開始在畫 result 的 td
同時 在 result 的迴圈 有三個欄位是需要 result2 的欄位資料才可以

這也是為何在離開迴圈之後 才會需要取得

ping1000 iT邦新手 5 級 ‧ 2021-08-19 17:44:21 檢舉

我是有 excel 格式~而且正常~
可是那個 excel 轉不了 PDF, 所以只能重刻

Hankz iT邦新手 2 級 ‧ 2021-08-19 18:24:35 檢舉

是這個意思?

$mysqli = mysqli_connect("localhost", "username", "password", "dbname");

$sql = "select * from tableA a";
$result = mysqli_query($mysqli, $sql);
$ctable = '<table>';
while ($row_result = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    $aaa = $row_result['aaa'];
    $bbb = $row_result['bbb'];

    $sql = "select b.*,c.* from tableB b join tableC c on b.date = c.date where c.billNo='".$row_result['BillNo']."'";
    $result2 = $mysqli->query($sql);
    $result_array = mysqli_fetch_all($result2, MYSQLI_ASSOC);
    
    foreach ($result_array as $row_result2) {
        $ccc = $row_result2['ccc'];
        $ddd = $row_result2['ddd'];
        $eee = $row_result2['eee'];
        
        if (count($result_array) > 2) { //大於二就要印好幾次?還是最後一次?還是第一次?
            $ctable.="<tr>" +
                "<td>$aaa</td>" +
                "<td>$bbb</td>" +
                "<td colspan="3">$ccc</td>" +
                "</tr>";
        } else {
            $ctable.="<tr>" +
                "<td>$aaa</td>" +
                "<td>$bbb</td>" +
                "<td>$ccc</td>" +
                "<td>$ddd</td>" +
                "<td>$eee</td>" +
                "</tr>";
        }
        
    } 
}

$ctable .= '</table>';
echo $ctable;
1
海綿寶寶
iT邦大神 1 級 ‧ 2021-08-19 17:47:41

與其通靈回答
我先來猜題目

如下圖
https://ithelp.ithome.com.tw/upload/images/20210819/20001787pGokxyyMwW.png
如果跟你的題目接近的話
底下是 source code 供參考
你可以任意修改成你要的結果
再用來提問

<HTML>
<?php
    $ctable = "<Table border=1 cellspacing=0 cellpadding=0>\n";
    $r1 = 0;
    while ($r1++ < 1) {
        $aaa = "row_result['aaa']";
        $bbb = "row_result['bbb']";
        
        $r2 = 0;
        while ($r2++ < 3) {
            $ccc = "row_result['ccc'] - $r2";
            $ddd = "row_result['ddd'] - $r2";
            $eee = "row_result['eee'] - $r2";
            $ctable.="<tr><td>Loop $r2</td><td>$aaa</td><td>$bbb</td><td>$ccc</td><td>$ddd</td><td>$eee</td></tr>\n";
    } 
    //total    
    if ($r2 > 0) {
            $ctable.="\n<tr><td>Total</td><td>$aaa</td><td>$bbb</td><td colspan='3'>$ccc</td></tr>\n";
    }
    $ctable.="\n<tr><td>Last Row</td><td>$aaa</td><td>$bbb</td><td>$ccc</td><td>$ddd</td><td>$eee</td></tr>\n"; //我在這裡要如何接到 $ccc,ddd,eee 動態的值?    
    }
    echo $ctable . "\n";
?>
</HTML>
1
小魚
iT邦大師 1 級 ‧ 2021-08-19 17:47:49

你的語法是不是少寫了甚麼?

1
通靈亡
iT邦高手 1 級 ‧ 2021-08-19 21:03:16

在畫表格的同時 我可以用 $row_result['aaa'] 去取得每一筆對應的值
但是當我要去得對應的 $ccc,$ddd,$eee 的值的時候 都確會是取得到最後一筆的資料

不論為什麼你要這樣寫,也不論你前面的資料來源是什麼。
如果單純就問題回答,你可以用 $row_result['aaa'] 當作 $ctable 的 key,將每一列 $row_result['aaa'] 的資料塞進去 $ctable

這樣你就可以用 $ctable[指定的 $row_result['aaa']] 抓到對應的資料列
簡單來說,就是使用 key => value 的資料結構來記錄,方便你之後用 key 來取得指定列的資料。

完整範例連結

例如:

<?php
$row_result = [];
$ctable = [];

$row_result['aaa'] = "1qaz@WSX";
$ctable[$row_result['aaa']] = "這不是肯德基";
echo "{$row_result['aaa']} => {$ctable[$row_result['aaa']]}"; 

出來就會是:

1qaz@WSX => 這不是肯德基

接著說明如何套用你的範例,這邊寫了一個模擬產生所有的資料列並記錄在 $table_data 與 $ctable:

<?php
// 模擬產生並記錄所有的 tr 資料
$table_data = [];

for ($i = 0; $i < 10; $i++) {
    $row_result = [
        "aaa" => "aaa$i",
        "bbb" => "bbb$i"
    ];
    
    $table_data[$row_result['aaa']] = [
        "aaa" => $row_result['aaa'],
        "bbb" => $row_result['bbb'],
        "ccc" => rand(1000, 3000),
        "ddd" => rand(1000, 3000),
        "eee" => rand(1000, 3000)
    ];
    
    $ctable[$row_result['aaa']] = 
        "<tr>
            <td>{$table_data[$row_result['aaa']]['aaa']}</td>
            <td>{$table_data[$row_result['aaa']]['bbb']}</td>
            <td>{$table_data[$row_result['aaa']]['ccc']}</td>
            <td>{$table_data[$row_result['aaa']]['ddd']}</td>
            <td>{$table_data[$row_result['aaa']]['eee']}</td>
        </tr>";
}
?>

紀錄完之後,可以用第一個範例的方式,將 aaa2 帶入 $table_data 的 key,得到 aaa2 列的 ccc 欄資料。
也可以用迴圈得到所有的資料列的欄位 ccc 的資料。

<?php
// 取得 aaa2 列的 ccc 欄資料
echo "<hr/>";
echo "\$table_data['aaa2']['ccc'] => {$table_data['aaa2']['ccc']}";

// 取得所有 tr 的 ccc 資料
foreach($ctable as $aaa_key => $aaa_value) {
    echo "<hr/>";
    echo "\$table_data['$aaa_key']['ccc'] => {$table_data[$aaa_key]['ccc']}";
}

輸出結果:

$table_data['aaa2']['ccc'] => 1047
________________________________________
$table_data['aaa0']['ccc'] => 2813
________________________________________
$table_data['aaa1']['ccc'] => 1385
________________________________________
$table_data['aaa2']['ccc'] => 1047
________________________________________
$table_data['aaa3']['ccc'] => 2858
________________________________________
$table_data['aaa4']['ccc'] => 1175
________________________________________
$table_data['aaa5']['ccc'] => 2754
________________________________________
$table_data['aaa6']['ccc'] => 1008
________________________________________
$table_data['aaa7']['ccc'] => 2628
________________________________________
$table_data['aaa8']['ccc'] => 2052
________________________________________
$table_data['aaa9']['ccc'] => 2685
0
pupuliao
iT邦新手 5 級 ‧ 2021-08-20 11:22:02

不太清楚你是要寫什麼,但看到你把 資料處理 跟 資料顯示 混在一起 就很不習慣

我自己的做法是 把 DB 撈資料 > 資料處理 > 資料顯示
然後 跟DB 溝通的部分 值接寫成class ,撈資料的時候只要SQL寫好,丟進去 就會回傳二維陣列
這是class 中撈資料的部分

var $dbRes_type= MYSQLI_ASSOC;
function getResult($query){
		//echo $query;
		$result = mysqli_query($this->dbCon,$query );

		while($row = @mysqli_fetch_array($result, $this->dbRes_type)){
			$data[] = $row;
		}
		if(isset($data)){
			return $data;
		}else{
			return false;
		}
	}

我要發表回答

立即登入回答