MySQL Class en While Loops

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Thomas Willemse

Thomas Willemse

24/06/2010 01:16:43
Quote Anchor link
Hallo allemaal,

Momenteel ondervind ik wat problemen bij het schrijven van een MySQL class methode die zou moeten werken met een while loop.

Voorbeeld:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php

$db
->Select("blaat", "foo");

while($row = $db->Fetch())
{
    ...
}


?>


In de class staat dit (alleen het belangrijkste weergegeven):

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php

public function Fetch()
{
    ...


    return mysql_fetch_array($this->result);

    ...
}


?>


Helaas krijg ik op deze manier maar 1 resultaat in de while loop.

Verder heb ik geprobeerd om de resultaten in een array terug te sturen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

public function Fetch()
{
    ...


    while($row = mysql_fetch_array($this->result))
    $row_arr[] = $row;

    return $row_arr;

    ...
}


?>


Helaas werkt ook dat niet.

Hoe kan ik dit oplossen?

Met vriendelijke groet,
Thomas
Gewijzigd op 24/06/2010 01:17:54 door Thomas Willemse
 
PHP hulp

PHP hulp

10/11/2024 22:42:39
 
Jelmer -

Jelmer -

24/06/2010 08:10:56
Quote Anchor link
Je Fetch functie geeft een array terug met alle resultaten, dus moet je een lus nemen die door ieder element van een array loopt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
foreach($db->Fetch() as $row) {
?>
 
Thomas Willemse

Thomas Willemse

24/06/2010 12:16:29
Quote Anchor link
Bedankt voor je reactie.

Heb je misschien ook een idee hoe ik while loops zou kunnen blijven gebruiken (met de Fetch() methode)?

Ik vind het zo vreemd dat het niet werkt, want als je het vergelijkt met de niet-OOP equivalent:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php

$query
= mysql_query("SELECT foo FROM blaat");

while($row = mysql_fetch_array($query))
{
    ...
}


?>


Dan doet mijn Fetch() functie toch eigenlijk hetzelfde?
 
SilverWolf NL

SilverWolf NL

24/06/2010 12:51:46
Quote Anchor link
"Dan doet mijn Fetch() functie toch eigenlijk hetzelfde?"

Dit is niet helemaal waar. In je Fetch() functie haal je alle resultaten al uit de resultset en stop je deze in een array. Als je wel een while-lus wil gebruiken zou je kunnen proberen om je Fetch-functie zo te maken:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?PHP
public function Fetch($result){
    return mysql_fetch_assoc($result);
}

?>


Wel zou je dan de code om de query uit te voeren in een andere functie moeten zetten, en die functie het resultaat terug laten geven. Lukt dat verder?
 
Thomas Willemse

Thomas Willemse

24/06/2010 13:43:05
Quote Anchor link
Het werkt!

Bedankt SilverWolf ;)
 
Pim -

Pim -

24/06/2010 17:42:15
Quote Anchor link
Leuker is een iterator (een object met foreach mogelijkheid) er van te maken.
Dan krijg je:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
foreach($result->fetch() as $row) {
    print_r($row);
}

?>


Let trouwens op dat je resultaten fetcht, dus geen database!
$db->fetch() is fout, $result->fetch() is goed.
Probeer je select query een resultaat object terug te laten geven.
Om je op weg te helpen.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
class DB
{
    public function select($query)
    {

        // Dus eerst een DB_Result object maken, gewoon een drager van het mysql result
        return new DB_Result(mysql_query($query));
    }
}


class DB_Result
{
    protected $result;

    public function __construct($result)
    {

        $this->result = $result;
    }


    public function fetch()
    {

         return mysql_fetch_assoc($this->result);
    }
}

?>

Als je dit begrijpt leg ik, of iemand anders wel die iterator uit
 
Thomas Willemse

Thomas Willemse

24/06/2010 18:09:04
Quote Anchor link
Bedankt voor je reactie, maar het probleem is al opgelost hoor ;)

Over de class var, ik gebruik $db zodat het duidelijk is dat het gaat om database gerelateerde functies, $fetch is wat dat betreft te vaag.

Ook werkte mijn class al met foreach.

Verder zie ik dat je in jouw voorbeeld 2 classes gebruikt... wellicht wat overbodig? Ik heb één MySQL class die alles afhandelt.

Met vriendelijke groet,
Thomas :-)
Gewijzigd op 24/06/2010 18:12:00 door Thomas Willemse
 
Pim -

Pim -

24/06/2010 18:19:28
Quote Anchor link
Met het schrijven van klasses neem ik aan dat je je aan OOP waagt. Hierbij is programmeren niet slechts dat code van boven naar onder loopt, maar de interactie tussen objecten. Je moet dan proberen elk object 1 specifieke taak te geven. Dit heeft grote voordelen die betrekking hebben op maintainability (onderhoudbaarheid?) van code, dus hoe goed je je deze achteraf nog kan wijzigen.

Elk object heeft een zo'n klein mogelijke taak en is dus zelf ook zo klein mogelijk (sommigen houden een maximum van 100 regels aan, dat is mij iets te extreem). De scheiding die ik voorstelde is in OOP-opzicht dus eerder een voordeel dan een nadeel.
 
SilverWolf NL

SilverWolf NL

25/06/2010 01:33:06
Quote Anchor link
Edit: Laat maar, heb het al gevonden. Voor degene die een Iterable class wil hebben, dit is er een:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?PHP
error_reporting(E_ALL);
mysql_connect("127.0.0.1","root","");
mysql_select_db("silverwolf_nl");

class MySQLextend{
    public function getResult($query){
        return new MySQLextendResult(mysql_query($query));
    }
}


class MySQLextendResult implements Iterator{
    private $position=1;
    private $rowdata;
    private $result;
    private $valid=true;
    public function __construct($result){
        $this->result=$result;
    }

    public function rewind(){
        if($this->position!==1){
            $this->position=1;
               mysql_data_seek($this->result,0);
            return;
        }
    }

    public function current(){
        return $this->rowdata;
    }

    public function key(){
        return $this->position;
    }

    public function next(){
        ++
$this->position;
        return;
    }

    public function valid(){
        $this->rowdata=mysql_fetch_assoc($this->result);
        return $this->rowdata!==false;
        
    }
}


$mysql=new MySQLextend;
//Testquery uitvoeren
$result=$mysql->getResult("SELECT message,id FROM news");

foreach($result as $row){
    var_dump($row);
}

?>


Veel plezier ermee!
Gewijzigd op 26/06/2010 01:40:08 door SilverWolf NL
 
Pim -

Pim -

25/06/2010 22:04:35
Quote Anchor link
Netjes.
Twee tips:
Wanneer de iterator voor het eerst gestart wordt, wordt rewind aangeroepen. De eerste keer hoef je niks te resetten: controleer eerst dus of $position veranderd is.

Je hoeft de rowcount niet op te slaan, num_rows kost veel kracht. Kijk bij valid() gewoon of $rowdata niet false is.
 
SilverWolf NL

SilverWolf NL

26/06/2010 01:42:09
Quote Anchor link
Pim, heb je commentaar meegenomen in de edit van het script (zie bovenstaande script voor aangepaste versie). Ben trouwens van plan deze uit te werken, omdat het altijd handig is om een class te hebben vergelijkbaar met mysqli als die niet beschikbaar is (uitgeschakeld ofzo). Zal hem posten als hij af is.
 
Pim -

Pim -

26/06/2010 09:01:59
Quote Anchor link
Zo is het niet netjes, next() hoort de data op te schuiven en deze wordt altijd eerst aangeroepen. Anders begin je ook met de tweede rij.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
string(18) "myIterator::rewind"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(0)
string(12) "firstelement"

string(16) "myIterator::next"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(1)
string(13) "secondelement"

string(16) "myIterator::next"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(2)
string(11) "lastelement"

string(16) "myIterator::next"
string(17) "myIterator::valid"

Dus ik zou het zo doen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
class MySQLextendResult implements Iterator{
    private $position=1;
    private $rowdata;
    private $result;
    private $valid=true;
    public function __construct($result){
        $this->result=$result;
    }

    public function rewind(){
        if($this->position!==1){
            $this->position=1;
            mysql_data_seek($this->result,0);
        }
    }

    public function current(){
        return $this->rowdata;
    }

    public function key(){
        return $this->position;
    }

    public function next(){
        ++
$this->position;
        $this->rowdata = mysql_fetch_assoc($this->result);
    }

    public function valid(){
        return $this->rowdata !== false;
    }
}

?>
 
SilverWolf NL

SilverWolf NL

26/06/2010 20:47:50
Quote Anchor link
Dan zou ik van de rewind functie nog even dit maken:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?PHP
    public function rewind(){
        if($this->position!==1){
            $this->position=1;
            mysql_data_seek($this->result,0);
        }
else{
            $this->rowdata=mysql_fetch_assoc($this->result);
        }
    }

?>


Omdat anders je eerste resultaat altijd null is.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.