MySQL Class en While Loops
Momenteel ondervind ik wat problemen bij het schrijven van een MySQL class methode die zou moeten werken met een while loop.
Voorbeeld:
In de class staat dit (alleen het belangrijkste weergegeven):
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
public function Fetch()
{
...
return mysql_fetch_array($this->result);
...
}
?>
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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
...
}
?>
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
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)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
$query = mysql_query("SELECT foo FROM blaat");
while($row = mysql_fetch_array($query))
{
...
}
?>
$query = mysql_query("SELECT foo FROM blaat");
while($row = mysql_fetch_array($query))
{
...
}
?>
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:
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?
Bedankt SilverWolf ;)
Dan krijg je:
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)
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
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);
}
}
?>
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
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
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.
Code (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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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);
}
?>
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
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.
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.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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"
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)
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
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;
}
}
?>
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;
}
}
?>
Code (php)
1
2
3
4
5
6
7
8
9
10
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);
}
}
?>
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.