webForumDet fria alternativet

Hämta värden från en array

4 svar · 815 visningar · startad av Jester73

Jester73Medlem sedan mars 2012121 inlägg
#1

Hej

Detta är lite av en uppföljningsfråga
Jag för söker göra en DAL class med mysqli

Så här ser den ut

class database {
    static $connect=FALSE;
    
    function __construct() {
        
        if(self::$connect===FALSE){
            self::$connect=new mysqli(DBHOST,DBUSER,DBPASSW,DBASE)or die("Kan inte ansluta");
            
        }
        
        if(self::$connect->connect_error){
            die("Får ej kontakt med databasen");
                
        }
}

    function dbselect($sql){ 
        if(!$res=self::$connect->query($sql)){
            echo $sql;
            die('Query error ' . self::$connect->error . '-' . self::$connect->errno);
            return FALSE;
        }
        $number_rows=$res->num_rows;
        
        if($number_rows==0){
            return FALSE;
        }
        elseif($number_rows==1){
            return $res->fetch_assoc();
        }
        elseif($number_rows>1){
            while($row=$res->fetch_assoc()){;
               $results[]=$row;    
            }
            return $results;
            
            
        }
    }
    
}

Jag skulle vilja hämta det så här

function lbokfmtrl(){
    $dbops=new database();
    $FormSize=array("W"=>485,"C1"=>345,"C2"=>140);
    $wdate=time()-(57*24*60*60);
    $Y=date("Y",$wdate);
    $M=date("m",$wdate);
    $warning=$Y."-".$M."-01";

    $sql="SELECT K.Kund_ID AS kid, K.Namn AS namn, K.Kundnr AS knr FROM tblKund AS K WHERE K.Kund_ID NOT IN (SELECT KundID FROM tblLBokf WHERE Period>='".$warning."') AND Avslutad = FALSE ORDER BY K.Kundnr ASC";	

    ?>
            <table id="alertlist" style="width: <?php echo $FormSize[W]?>px;">
          <tbody>
            <tr>
              <th colspan="2">Kunder med sent månadsmaterial
              </th>
            </tr>
            <tr>
              <td class="subrubr">Kund
              </td>
              <td class="subrubr">Senaste Period
              </td>
            </tr>
            <?php
            $res=$dbops->dbselect($sql);
            var_dump($res);
            foreach($res as $rows){
                    $rowstyle=($altstyle % 2 == 1 ? "class=\"alt\"" : "");
                    print "<tr $rowstyle>";
                    print "<td style=\"width:".$FormSize['C1']."px;\"><a href=\"material.php?action=2\" class=\"lista\">" . $rows->knr . " - " . $rows->namn ."</a>";
                    print "</td>";
                    $sql2="SELECT MAX(Period) AS Per FROM tblLBokf WHERE KundID=".$rows->kid;
                    $subres=$dbops->dbselect($sql2);
                    print "<td style=\"width:".$FormSize['C2']."px;\">";
                    if (!$subres){
                            periodFormat($subres);
                    }
                    else {
                            print "Uppgift saknas";
                    }
                    print "</td>";
                    print "</tr>";
                    $altstyle++;
            }
            
           ?>
          </tbody>
        </table>
        <?php
    }

Men det går inte för resultatet verkar bli en array med en under array då jag hämtar 3 uppgifter från databasen.

resultatet av ovan kod ser ni här
http://experio.myqnapcloud.com/solboadmin/

Vill ju bara kunna hämta på samma sätt som om jag hade myqli_fetch_assoc() direkt i koden eller går inte det? :)

b242569Medlem sedan sep. 20051 760 inlägg
#2

Kanske att de 2 sista raderna i nedre koden

 \<?php 

}

ska tas bort. Det verkar som en början på något utan slut och slut på något annat.

}

kanske ska placeras högre upp och

<?php

ska tas bort.

metalboyMedlem sedan jan. 2005953 inlägg
#3

Tar tillbaka en del av det jag skrev här: http://www.webforum.nu/showthread.php?t=194643#2

I din dbselect-metod bör du när bara en rad returneras från databasen returnera en array med bara ett element (resultatet från databasen). Du behöver inte skilja mellan 1 rad och fler än 1 rad. Skriv om

elseif($number_rows==1){
    return $res->fetch_assoc();
}
elseif($number_rows>1){
    while($row=$res->fetch_assoc()){;
        $results[]=$row;    
    }
    return $results;
}

till det här

else {
    $results = array();
    while ($row = $res->fetch_assoc()) {
        $results[] = $row;
    }
}

Ser att du i koden använder skrivsättet $rows->kid. Om du vill göra det ska du använda fetch_object() istället för fetch_assoc(). Använder du fetch_assoc() ska du istället skriva $rows['kid'].

Du behöver också tänka på vad som händer om din SQL-fråga returnerar 0 rader. I dagsläget returnerar din metod FALSE när detta inträffar. Det kommer att innebära att din foreach-loop generar ett felmeddelande av typen E_WARNING ("Invalid argument supplied for foreach"). Om du istället helt låter bli att kolla hur många rader som SQL-frågan returnerade och bara loopar igenom resultatet så kommer din metod då att returnera en tom array vid de tillfällen som SQL-frågan returnerar 0 rader. Detta kan hanteras av foreach utan felmeddelanden (loopen körs då inte alls).

Alltså, i din dbselect-metod kan du ha så här:

function dbselect($sql){ 
    if(!$res=self::$connect->query($sql)){
        echo $sql;
        die('Query error ' . self::$connect->error . '-' . self::$connect->errno);
        return FALSE; // Den här raden behövs inte eftersom du kör die på raden ovanför ;)
    }
    $results = array();
    while($row=$res->fetch_assoc()){
        $results[]=$row;    
    }
    return $results;
}
Jester73Medlem sedan mars 2012121 inlägg
#4

Stort TACK!!! :)
Nu verkar det fungera, tycker att jag provat denna lösning tidigare men har väl inte varit så metodisk i min debugg :)
Nu är det bara underfrågan som inte lirar riktigt
Kan jag använda samma instans i underfrågan som i första SELECT?

metalboyMedlem sedan jan. 2005953 inlägg
#5

Jester73 skrev:

Nu är det bara underfrågan som inte lirar riktigt
Kan jag använda samma instans i underfrågan som i första SELECT?

Ja det ska gå bra. Däremot ser din kod lite konstig ut här:

if (!$subres){
    periodFormat($subres);
}

Vad du säger är att om anropet till dbselect() returnerar FALSE så ska periodFormat() anropas med FALSE som argument till funktionen. Är det verkligen så du menar? Jag tror att du vill ta bort utropstecknet :)

424 ms totalt · 3 externa anrop · v20260731065814-full.fb544a5a
296 ms — hämta forumlista (db)
125 ms — hämta statistik (db)
296 ms — hämta tråd, inlägg och bilagor (db)