[MySQL] Database driver i.c.m. fetchen

Pagina: 1
Acties:
  • 157 views sinds 30-01-2008
  • Reageer

  • Acolyte
  • Registratie: Oktober 2002
  • Laatst online: 28-08-2024
Ik ben bezig met het database onafhankelijk maken van mijn scripts, en dat doe ik aan de hand van een database class waar alle functies in staan:
PHP:
1
2
3
4
5
6
7
<?php
openConnection();
doQuery();
doFetchNext();
numRows();
fatalError();
?>


Deze methode heb ik afgekeken van een database class van phpclasses.org.
Maar als ik dit werkend wil krijgen werkt dit prima op 1 ding na. Een query uitvoeren lukt, het aantal rows opvragen ook, maar fetchen, dus 1 voor 1 in een while loop uitputten gaat fout. Op zich laadt hij alle gegevens in, maar helaas 1 keer teveel. Voorbeeldje:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
//db
$DB = new DB;
$DBconn = $DB->openConnection();

//queries
$q_nofetch = "SELECT userID, userFullName, userAddress FROM users";
$result = $DB->doQuery($q_nofetch, 0, "", __LINE__, __FILE__);

/*
    Geeft: Het aantal rijen = 3
*/
echo "Het aantal rijen van je query = ".$DB->numRows()."<br /><br />";

$q_fetch = $DB->doQuery("SELECT userID, userFullName, userAddress FROM users", __LINE__, __FILE__);

/*
    Geeft: 3 x userID, userFullName, userAddress
    + een error
*/
while($result = $DB->doFetchNext("row", __LINE__, __FILE__))
{
    echo "userID = ".$result[0]."<br />";
    echo "userFullName = ".$result[1]."<br />";
    echo "userAddress = ".$result[2]."<br />";
    echo "<br />";
}
?>

Nu, die error hebben we allemaal weinig aan. MySQL zelf geeft geen error terug, maar mijn eigen database error functie wel. Hij wordt dus aangeroepen, en veel meer dan regelnummer en bestandsnaam komt er niet terug, en dat is gewoon de regel waar de while() wordt aangeroepen in bovenstaand voorbeeld.

Hij wil dus verdergaan na 3 rondes, maar er is geen data meer. Mijn doFetchNext ziet er zo uit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
    function doFetchNext($fetchMethod = "row",  $line = 0, $file = _DB_FETCH_FILE_NA)
    {
        //if(!isset($query)) 
            //die($this->dbFatalError(_DB_QUERY_NO_QUERY, '', $linenumber, $file)); 
        if($this->resSource != NULL)
        {
            switch ($fetchMethod)
            {
                case "row":
                echo "rows | type = ".gettype($this->resSource)." ";
                $result = @mysql_fetch_array($this->resSource, MYSQL_NUM) 
                            or die($this->dbFatalError(_DB_QUERY_FETCH_NUM_FAILED, $this->query, $line, $file));
                break;
                
                case "assoc":
                $result = @mysql_fetch_array($this->resSource, MYSQL_ASSOC) 
                            or die($this->dbFatalError(_DB_QUERY_FETCH_ASSOC_FAILED, $this->query, $line, $file));
                break;
                
                default:
                die($this->dbFatalError(_DB_QUERY_FETCH_INVALID_METHOD, $this->query, $line, $file));
                break;
            }
            return $result;
        }
        else
        {
            return false;
        }

    }
?>

$this->resSource komt van doQuery, de resource van de query dus:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
<?php
    function doQuery($query, $linenumber = 0, $file = _DB_QUERY_FILE_NA)  
    { 
        if(!isset($query)) 
            die($this->dbFatalError(_DB_QUERY_NO_QUERY, '', $linenumber, $file)); 
             
        $this->resSource = @mysql_query($query) 
                        or die($this->dbFatalError(_DB_QUERY_FAILED, $query, $linenumber, $file)); 
            $this->query = $query;
            return true;
    }
?>

Nu is het dus even de vraag, hoe ik het nou voor elkaar krijg dat zodra de query geen data meer heeft, hij false returned, en dus stopt met de while lus. Hij doet hem nu een keer te veel. Verder werkt het ding gewoon naar behoren.

  • mocean
  • Registratie: November 2000
  • Laatst online: 25-11 11:02
mysql_fetch_array geeft een false als er geen datarow meer is, die false triggert jouw die() functie ($this->dbFatalError) denk ik.
Deze false is echter geen error, dus je zou de foutafhandeling daar anders moeten doen, zodat false in de return variabele komt.

Koop of verkoop je webshop: ecquisition.com


  • Acolyte
  • Registratie: Oktober 2002
  • Laatst online: 28-08-2024
mocean schreef op zaterdag 17 maart 2007 @ 11:51:
mysql_fetch_array geeft een false als er geen datarow meer is, die false triggert jouw die() functie ($this->dbFatalError) denk ik.
Deze false is echter geen error, dus je zou de foutafhandeling daar anders moeten doen, zodat false in de return variabele komt.
Maar hoe stel je voor dat ik dat doe dan?
In doFetchNext() wordt al eerst gecontroleerd of resSource niet NULL is. Nu zou het zo kunnen zijn dat die nooit NULL wordt omdat een resource nou eenmaal een resource blijft, maar hoe controleer ik dan van tevoren of er nog wel een rij is, zonder fetch_array ook daadwerkelijk aan te roepen? Er moet is van if(iets == false) aan vooraf gaan lijkt mij...

Ik snap wat je verteld, en het is ook erg logisch. Maar nu moet ik op een nette manier controleren op het false of niet false zijn ervan.

  • mocean
  • Registratie: November 2000
  • Laatst online: 25-11 11:02
False wil zeggen geen rows meer. "Returns an array that corresponds to the fetched row, or FALSE if there are no more rows"

Je kan
PHP:
1
2
3
$result = @mysql_fetch_array($this->resSource, MYSQL_NUM) 
 or die($this->dbFatalError(_DB_QUERY_FETCH_NUM_FAILED, $this->query, $line, $file));
break;

versimpelen tot
PHP:
1
2
$result = @mysql_fetch_array($this->resSource, MYSQL_NUM) 
break;


Punt is dus het veriefieren van je resource, dat zie ik ook even niet hoe dat gemakkelijk kan.
Je wil eigenlijk een functie als is_valid_resource(this->resSource), maar ik weet zo niet hoe je die kan maken.

Edit: Wellicht met: is_resource()

Koop of verkoop je webshop: ecquisition.com


  • Acolyte
  • Registratie: Oktober 2002
  • Laatst online: 28-08-2024
Ik heb het uiteindelijk precies zo opgelost zoals jij zegt. Gewoon de or die() weghalen bij de fetch.
Uiteindeljk was dat ook wel wat onzinnig, want als er ergens al iets fout gaat, gebeurt dat bij het submiten van de query. En daar wordt ie prima opgevangen.
Nog wel even een check ingebouwd die checkt of de resource ook bestaat. Dat men niet zomaar doFetchNext() kan aanroepen zonder query.