[OOP] PDO verwerken in class.

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Kwastie

Kwastie

14/05/2008 17:36:00
Quote Anchor link
Ik heb aantal weken geleden dit script gemaakt: http://www.phphulp.nl/php/scripts/4/1334/

Ik heb wat kleine dingen veranderd aan dit script en ik heb ipv standaard queries gebruik gemaakt van de PDO 'plugin' van php.

Met standaard programmeren (dus niet OOP) werkt PDO perfect. Maar zo gauw ik dit in mijn class verwacht krijg ik de Error:
"Fatal error: Call to a member function quote() on a non-object in C:\wamp\www\classes\Auth\clsAuthentication.php on line 29"

Mijn script kun je hier vinden: http://rafb.net/p/KC3sGL62.html

Ik heb wel een oplossing, de PDO connection in de constructor zetten, maar dit is ver van praktisch. Volgens mij is extenden ook niet een goede oplossing.
Weet iemand hoe ik dit werkend krijg ?
Gewijzigd op 01/01/1970 01:00:00 door Kwastie
 
PHP hulp

PHP hulp

21/09/2021 00:53:33
 
TJVB tvb

TJVB tvb

14/05/2008 17:40:00
Quote Anchor link
Op dat punt is $db niet bekent.
Er zijn eigenlijk een paar mogelijkheden:
een class om pdo schrijven die singleton is waardoor je ter plekke een instance kunt "maken" en gebruiken
De $db variabele meegeven aan de class (en dus binnen de class opslaan)
Een registry class schrijven waar je de variabele $db aan meegeeft, die classe kun je dan overal om die variabele vragen

oplossing 2 is misschien het makkelijkst, maar het ligt meestal aan de omgeving wat hier het handigste is.
Gewijzigd op 01/01/1970 01:00:00 door TJVB tvb
 
Jurgen assaasas

Jurgen assaasas

14/05/2008 18:23:00
Quote Anchor link
Dit lijkt mij de beste oplossing (zoals het hoort?):

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
<?php

class My_class
{

   private $datalink;

    public function __construct(PDO $db)
    {

        $this->datalink = $db;
    }

}


$db = new PDO(....);

$my_class = new My_class($db)

?>
Gewijzigd op 01/01/1970 01:00:00 door Jurgen assaasas
 
Cedric

Cedric

14/05/2008 18:28:00
Quote Anchor link
Ben je van plan veel gebruik te maken van de database, dan is het inderdaad interessant om de registery class te gebruiken. Zoals hierboven gezegd kan je dan gewoon de database aanroepen wanneer je wilt (omdat registry een singleton is). Maar gebruik je gewoon even snel een connectie naar de database, dan kan jet het ook 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
<?php
class Myclass
{
    protected $connection;
    
    public function __construct(PDO $connection)
    {

        $this->connection = $connection;
    }


    public function myfunction()
    {

        $this->connection->query("SELECT * FROM table");
        // continue..
    }
}

?>


<?php
$connection
= new PDO('mysql:host=localhost;dbname=db', 'user', 'pass');
$myclass = new Myclass($connection);
?>


Edit:
Jurgen was me voor ;)
Gewijzigd op 01/01/1970 01:00:00 door Cedric
 
Kwastie

Kwastie

14/05/2008 20:33:00
Quote Anchor link
Dat zou betekening dat ik in elke class die bij de database zou moeten komen zo'n class moet gebruiken? Maar dat kan toch niet dé oplossing zijn..

Opties:
- elke class een PDO database connectie meegeven
- $_GLOABAL gebruiken
- elke class extenden op de PDO class

Ik vind eigelijk alle 3 de oplossingen niets.
 
Jan geen

Jan geen

14/05/2008 20:46:00
Quote Anchor link
Een register werkt ook prima.

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
<?php
class Register {
    
    static public function DB() {
        static $db;
        if(!$db) {
            $db = new PDO('mysql:host='.SERVER.';dbname='.DB, USER, PASS);
            $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }

        return $db;
    }
}


// Dan kan je het op de volgende manier pdo aanroepen
public function findById($id) {
    $pdo = Register::DB();
    $stmt = $pdo->prepare
    // enz
}
?>


Normaal gesproken geef je de klasses die je nodig hebt mee via de constructor maar omdat een database class zo centraal staat vind ik dit ook wel een mooie oplossing. Het Register kan je dan ook voor andere dingen zoals een template engine gebruiken.
Gewijzigd op 01/01/1970 01:00:00 door Jan geen
 
Hipska BE

Hipska BE

14/05/2008 20:47:00
Quote Anchor link
die 3de optie is zeker al niet correct..

optie 1 is de meest correcte.
 
Jelmer -

Jelmer -

14/05/2008 20:51:00
Quote Anchor link
Ik gebruik zelf de eerste, omdat je dan volledige controle hebt over welke instantie van PDO je klasse gebruikt (mocht je meerdere databases gebruiken)

Oplossing 2 is een beetje twijfelachtig, omdat je de klasse moet kennen wil je weten dat je een global variabele nodig hebt, je de variabele gemakkelijk kan vervangen met iets verkeerts, ook per ongeluk waardoor plotseling de zooi niet meer werkt. En al je klassen maken gebruik van dezelfde PDO instantie.

Oplossing 3 is niet te doen. Dat zou inhouden dat iedere instantie een eigen verbinding opzet, en dat je de constructor als het ware kwijt bent aan PDO, je zal iedere instantie al de verbindingsgegevens mee moeten geven. Dat is nog erger dan oplossing 1. Erger, je extend PDO om functionaliteit terwijl je eigenlijk alleen moet extenden wanneer een klasse een specifiekere variant is van een andere klasse. Extenden doe je bij een "is een", niet bij "gebruikt een". Extend je PDO, kan je niets anders meer extenden.

In mijn ogen is oplossing nummero uno de prettigste. $pdo aan de constructor meegeven is relatief weinig moeite en geeft je toch de meest makkelijk te begrijpen code en de meeste flexibiliteit.
 
Kwastie

Kwastie

14/05/2008 21:31:00
Quote Anchor link
Ik ga dan maar voor optie 1, ik had een mooier oplossing verwacht. Als die er niet is word het lastig, en bij nader inzien is het niet een hele slechte oplossing.

Met optie 2 en 3 gaat de 'flexibiliteit' erg omlaag.
 
Jelmer -

Jelmer -

14/05/2008 21:53:00
Quote Anchor link
Optie 2 zou je ook nog ietsjes anders kunnen doen, zodat je niet last hebt van het risico dat de variabele ineens verdwenen is. Je zou een gewone functie kunnen maken die een verbinding teruggeeft.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php
function database()
{

    static $pdo;
    
    if(!$pdo) {
        $pdo = new PDO('...');
    }

    
    return $pdo;
}

?>

Of belachelijk kort
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
function database()
{

    static $pdo;
    return $pdo ? $pdo : $pdo = new PDO('...');
}

?>


Op deze manier kan je database instantie niet worden overschreven, wordt hij pas aangemaakt wanneer hij echt nodig is, en krijg je een duidelijke foutmelding dat er iets mis is. Je houdt het probleem dat je maar 1 verbinding binnen alle instanties kan gebruiken. Maar in voornamelijk kleine applicaties zou dat niet een probleem hoeven zijn. En dan is het wel makkelijk.
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
<?php
class Foo {
    public function find($id)
    {

        $stmt = database()->prepare('SELECT * FROM tabel WHERE id = :id');
        $stmt->bindParam(':id', $id, PDO::PARAM_INT);
        if($stmt->execute()) {
            return $stmt->fetch(PDO::FETCH_ASSOC);
        }
else {
            return false;
        }
    }
}

?>
 
Martiveen -

Martiveen -

14/05/2008 23:39:00
Quote Anchor link
Vraagje Jelmer, moet je die functie binnen de class aanmaken. Of buiten de class?
 
Jelmer -

Jelmer -

14/05/2008 23:57:00
Quote Anchor link
buiten de klasse. Gewoon een ordinaire saaie functie. Je zou hem in je config file kunnen zetten, op dezelfde plek waar je anders je logingegevens van je db plaatst (ervan uitgaande dat je een php bestand daarvoor gebruikt, niet een ini. In dat geval zou ik hem gewoon in de index.php dumpen)
 
Emmanuel Delay

Emmanuel Delay

29/06/2008 22:15:00
Quote Anchor link
Wat ik meestal doe: ik heb een object $m_mysql. Ik heb een class waarin ik een aantal mySQL methodes bundel.

$result = $m_mysql->doSql($sql); zorgt er voor dat er een connectie wordt gemaakt, dat de query wordt uitgevoerd, connectie verbroken, result weergegeven. De connectie gegevens zitten in dat object. Overal waar ik mySQL nodig heb binnen een class geef ik dat object $m_mysql mee aan de andere class.

Maar inderdaad, het is ook simpel om je config file gewoon een beetje anders te gebruiken.

ipv.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?
$db_user
= 'root';
$db_pasword = 'huppeldepup';
...

?>


maak je iets als
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?
function getDbConfig()
{

$result = array('root', 'buppeldepup', ...);
return $result;
}

?>


Dan kan je getDbConfig() overal in je site gebruiken.
 



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.