OOP database

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 3 4 volgende »

Lord Gaga

Lord Gaga

05/01/2013 19:01:31
Quote Anchor link
Hallo,

Ik ben nog steeds bezig met het leren van OOP, maar er is nog steeds iets dat ik niet snap.
Neem bijvoorbeeld deze code:

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
52
53
54
55
<?php
class Person
{
    private $_prefix;
    private $_givenName;
    private $_familyName;
    private $_suffix;
    
    public function setPrefix($prefix)
    {

        $this->_prefix = $prefix;
    }

    
    public function getPrefix()
    {

        return $this->_prefix;
    }

    
    public function setGivenName($gn)
    {

        $this->_givenName = $gn;
    }

    
    public function getGivenName()
    {

        return $this->_givenName;
    }

    
    public function setFamilyName($fn)
    {

        $this->_familyName = $fn;
    }

    
    public function getFamilyName()
    {

        return $this->_familyName;
    }

    
    public function setSuffix($suffix)
    {

        $this->_suffix = $suffix;
    }

    
    public function getSuffix()
    {

        return $_suffix;
    }
}


$person = new Person();
$person->setPrefix('Mr.');
$person->setGivenName('John');

echo $person->getPrefix() . ' ' . $person->getGivenName();
?>


Hiermee kun je dus een 'persoon' aanmaken en aanpassen, die gegevens worden dan dus in de variabelen van de class opgeslagen.
Maar dan kun je ze alleen aanroepen op de pagina waar je dus die personen hebt aangemaakt.

Om ze overal aan te kunnen roepen kun je ze dus bijvoorbeeld opslaan in een database, maar hoe moet je dit nou precies in die class verwerken?
Moet je de variabelen die bovenaan in de class zijn weghalen en alle getters en setters een select / update query laten uitvoeren om gegevens op te halen en aan te passen?
En hoe haal je dan gegevens op van een persoon dat al bestaat?

Ik hoop dat iemand me hier antwoord op kan geven.

Alvast bedankt!
 
PHP hulp

PHP hulp

26/12/2024 09:42:34
 
Wouter J

Wouter J

05/01/2013 19:16:16
Quote Anchor link
Er zijn vele methoden waarop je met OO kunt connecten met een database.

Sowieso moet je OO altijd alle verantwoordelijkheden delen, een method heeft maar 1 verantwoordelijkheid en een klasse ook. Je kunt dus niet de klasse en de gegeven vast laten houden en interactie laten hebben met de Database.

De meest gebruikte manier is om een DataMapper te gebruiken. Het eind resultaat ziet er dan zo uit:
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
<?php

$dbal
= new PDO(...);
$personMapper = new PersonMapper($dbal);

// create
$person = new Person();
$person->setName('Kees');
$person->setAge(32);

$personMapper->create($person); // bijv. `INSERT persons (name, age) VALUES ('kees', 32)`

// read

$person = $personMapper->findById(4); // bijv. `SELECT ... FROM persons WHERE id = 4`

// update

$person->setAge(54);

$personMapper->save($person); // bijv. `UPDATE persons SET age = 54 WHERE id = ...`

// delete

$personMapper->remove($person); // bijv. `DELETE FROM persons WHERE id = ...`
?>


Om te zien hoe dit in een klasse eruit ziet kun je eens naar 1 van deze uitleggen en code voorbeelden kijken: http://www.phphulp.nl/php/forum/topic/datamappers/85007/last/ , http://www.phphulp.nl/php/forum/topic/oop-in-combinatie-met-database/81754/#580025 en http://www.phphulp.nl/php/forum/topic/oop-gedachtengang/85017/1/#606620


Je kan ook bijv. active record gebruiken: http://www.phphulp.nl/php/forum/topic/applicatie-naamgeving/81370/3/#578116 en http://www.phphulp.nl/php/forum/topic/activerecord-en-method-chaining/83025/#590652
 
Lord Gaga

Lord Gaga

05/01/2013 19:28:14
Quote Anchor link
Bedankt! Ik heb wel eens iets gelezen over dataMappers maar heb er nooit iets van gesnapt, nu wel! (Althans, ik heb de posts snel doorgekeken, ik ga ze morgen helemaal lezen.)

Edit:
Ik heb nu het volgende gemaakt:

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
<?php
//> Database
    // Database Configuration

    $SQL = new mysqli('', '', '', '');
    
    // Database Connection
    if ($SQL->connect_errno)
    {

        trigger_error('Fout bij verbinding: ' . $SQL->error);
    }

    
    // Database Charset
    $SQL->set_charset('utf8');
//>
    
//> Classes
    //> User
        // User Interface

        interface UserInterface
        {
            public function setID($ID);
            public function setActivated($activated);
            public function setUsername($username);
            public function setPassword($password);
            public function setEmail($email);
            public function setBirthday($birthday);
            public function setGender($gender);
            public function setDateTime($dateTime);
            public function setIP($IP);
            
            public function getID();
            public function getActivated();
            public function getUsername();
            public function getPassword();
            public function getEmail();
            public function getBirthday();
            public function getGender();
            public function getDateTime();
            public function getIP();
        }

        
        // User Class
        class User implements UserInterface
        {
            // Variables
            private $ID;
            private $activated;
            private $username;
            private $password;
            private $email;
            private $birthday;
            private $gender;
            private $dateTime;
            private $IP;
            
            // Constructor
            public function __construct($activated, $username, $password, $email, $birthday, $gender, $dateTime, $IP)
            {

                $this->activated    = $activated;
                $this->username        = $username;
                $this->password        = $password;
                $this->email        = $email;
                $this->birthday        = $birthday;
                $this->gender        = $gender;
                $this->dateTime        = $dateTime;
                $this->IP            = $IP;
            }

            
            // Set ID
            public function setID($ID)
            {

                $this->ID = $ID;
            }

            
            // Set Activated
            public function setActivated($activated)
            {

                $this->activated = $activated;
            }

            
            // Set Username
            public function setUsername($username)
            {

                $this->username = $username;
            }

            
            // Set Password
            public function setPassword($password)
            {

                $this->password = $password;
            }

            
            // Set Email
            public function setEmail($email)
            {

                $this->email = $email;
            }

            
            // Set Birthday
            public function setBirthday($birthday)
            {

                $this->birthday = $birthday;
            }

            
            // Set Gender
            public function setGender($gender)
            {

                $this->gender = $gender;
            }

            
            // Set DateTime
            public function setDateTime($dateTime)
            {

                $this->dateTime = $dateTime;
            }

            
            // Set IP
            public function setIP($IP)
            {

                $this->IP = $IP;
            }

            
            // Get ID
            public function getID()
            {

                return $this->ID;
            }

            
            // Get Activated
            public function getActivated()
            {

                return $this->activated;
            }

            
            // Get Username
            public function getUsername()
            {

                return $this->username;
            }

            
            // Get Password
            public function getPassword()
            {

                return $this->password;
            }

            
            // Get Email
            public function getEmail()
            {

                return $this->email;
            }

            
            // Get Birthday
            public function getBirthday()
            {

                return $this->birthday;
            }

            
            // Get Gender
            public function getGender()
            {

                return $this->gender;
            }

            
            // Get DateTime
            public function getDateTime()
            {

                return $this->dateTime;
            }

            
            // Get IP
            public function getIP()
            {

                return $this->IP;
            }
        }

        
        // User Mapper
        class UserMapper
        {
            // Variables
            private $SQL;
            
            // Constructor
            public function __construct(MySQLi $SQL)
            {

                $this->SQL = $SQL;
            }

            
            // Get By ID
            public function getByID($ID)
            {

                $query = '
                    SELECT
                        *
                    FROM
                        users
                    WHERE
                        ID = '
. $this->SQL->real_escape_string($ID);
                $result = $this->SQL->query($query);
                $rUser = $result->fetch_assoc();
                
                return $this->populate($rUser);
            }

            
            // Populate
            public function populate(array $data)
            {

                $user = new User($data['activated'], $data['username'], $data['password'], $data['email'], $data['birthday'], $data['gender'], $data['dateTime'], $data['IP']);
                $user->setID($data['ID']);
                
                return $user;
            }

            
            // Save
            public function save(User $user)
            {

                $query = '
                    UPDATE
                        users
                    SET
                        activated = '
. $this->SQL->real_escape_string($user->getActivated()) . ',
                        username = "'
. $this->SQL->real_escape_string($user->getUsername()) . '",
                        password = "'
. $this->SQL->real_escape_string($user->getPassword()) . '",
                        email = "'
. $this->SQL->real_escape_string($user->getEmail()) . '",
                        birthday = "'
. $this->SQL->real_escape_string($user->getBirthday()) . '",
                        gender = "'
. $this->SQL->real_escape_string($user->getGender()) . '",
                        dateTime = "'
. $this->SQL->real_escape_string($user->getDateTime()) . '",
                        IP = "'
. $this->SQL->real_escape_string($user->getIP()) . '"
                    WHERE
                        ID = '
. $this->SQL->real_escape_string($user->getID());
                $this->SQL->query($query);
            }
        }

    //>
//>

// Create UserMapper

$userMapper = new UserMapper($SQL);

// Get User
$user = $userMapper->getById(1);

// Display Username
echo $user->getUsername();
?>


Het werkt, maar is dit zo goed?

En dan heb ik nog een vraagje:
Bij 'save' word ALLES opnieuw opgeslagen, hoe zorg ik ervoor dat alleen het aangepaste wordt opgeslagen? Want stel dat je een pagina bezoekt, dan worden al jouw gegevens in dat User object gezet. als er in tussentijd iets veranderd in de user tabel en jij voert op die pagina een save uit, dan wordt dat overschreven..
Gewijzigd op 06/01/2013 13:20:52 door Lord Gaga
 
Lord Gaga

Lord Gaga

07/01/2013 19:33:00
Quote Anchor link
Ik probeerde mijn vorige bericht te editen om te vragen of iemand wist hoe ik dat saven moet aanpassen, maar ik kan het bericht niet editen op een of andere manier.. dus dan maar een nieuw bericht.. :x
Gewijzigd op 07/01/2013 19:41:10 door Lord Gaga
 
Moose -

Moose -

07/01/2013 19:41:01
Quote Anchor link
Kijk ook eens hier naar: http://laravel.com/docs/database/eloquent Ik vind dat zelf een zeer fijne manier van werken met models en de database

Edit: dat alle data van je user gesaved wordt is toch juist goed? Je roept alleen maar een save aan als je ook daadwerkelijk de user van dat moment wil opslaan. Ik kan me geen scenario indenken waarin je dit niet zou willen
Gewijzigd op 07/01/2013 19:43:42 door Moose -
 
Erwin H

Erwin H

07/01/2013 19:43:17
Quote Anchor link
Sla niet elk property van user op in een apart private property, maar in een array. Op die manier ben je erg flexibel, want een nieuw property kan je eenvoudig toevoegen. Voor een update kan je dan ook snel zien wat wel en niet is aangepast, mist je alleen die gegevens in de array zet die zijn aangepast. Alles wat in de array zit moet je dan udpaten in de database niets meer.
 
Wouter J

Wouter J

07/01/2013 19:45:06
Quote Anchor link
Wat Not Moose laat zien is Active Record, niet dat het slecht is maar ik hou er niet van (en het is typisch Laravel style: lekker static).

De save functie is goed zo, dat kun je niet veranderen. Wat je je eerder moet af vragen is hoe er plotseling iets kan veranderen in de DB, dit zal altijd via de User en UserMapper moeten.
 
Lord Gaga

Lord Gaga

07/01/2013 19:49:06
Quote Anchor link
Wouter J op 07/01/2013 19:45:06:
Wat Not Moose laat zien is Active Record, niet dat het slecht is maar ik hou er niet van (en het is typisch Laravel style: lekker static).

De save functie is goed zo, dat kun je niet veranderen. Wat je je eerder moet af vragen is hoe er plotseling iets kan veranderen in de DB, dit zal altijd via de User en UserMapper moeten.


Nou, in dit geval is dat nog niet echt mogelijk, maar stel dat ik een veld heb waarin het aantal 'coins' van de gebruiker worden opgeslagen.

Als die gebruiker bijvoorbeeld zijn email wil veranderen, dan gaat hij naar zijn settings, op dat moment wordt, neem ik aan, een user object gemaakt met daarin al zijn data.

Als er ondertussen bijvoorbeeld een moderator is die hem een x aantal coins geeft, worden die weer overschreven op het moment dat de gebruiker zijn email aanpast.

Of zie ik dit nu verkeerd?
 
Wouter J

Wouter J

07/01/2013 19:50:34
Quote Anchor link
Een User object wordt als het goed is direct bij het controleren van de user gemaakt, dus als een van de eerste dingen in je request flow.
 
Lord Gaga

Lord Gaga

07/01/2013 19:52:02
Quote Anchor link
Wouter J op 07/01/2013 19:50:34:
Een User object wordt als het goed is direct bij het controleren van de user gemaakt, dus als een van de eerste dingen in je request flow.


Maar wordt die gemaakt op het moment als ik de pagina aanroep of op het moment dat ik ook daadwerkelijk gegevens op wil slaan?
 
Wouter J

Wouter J

07/01/2013 19:53:28
Quote Anchor link
Als je op een settings pagina komt moet je eerst kijken of die user wel op de settings pagina mag komen, dan maak je dus al een USer object aan.
 
Lord Gaga

Lord Gaga

07/01/2013 19:55:59
Quote Anchor link
Ja, maar dan worden de gegevens toch overschreven?

Stel nou dat jij ergens je email wilt veranderen, dus je gaat naar die pagina en er wordt meteen een userobject aangemaakt:

naam: Wouter J
email: [email protected]
munten: 100

Terwijl jij op die pagina zit is er ergens iemand die jou 10 munten geeft.

In de database staat dus nu dat jij 110 munten hebt, terwijl in jouw user object nog staat dat jij er 100 hebt.

Dan sla jij je nieuwe email op, maar omdat alle gegevens worden opgeslagen, worden die 100 munten dus ook opnieuw in de database gezet, waardoor jij nu opeens maar weer 100 munten hebt..
Gewijzigd op 07/01/2013 19:58:23 door Lord Gaga
 
Moose -

Moose -

07/01/2013 20:01:23
Quote Anchor link
Daar zou je dan een koppel tabel voor kunnen maken
 
Lord Gaga

Lord Gaga

07/01/2013 20:03:57
Quote Anchor link
Not Moose op 07/01/2013 20:01:23:
Daar zou je dan een koppel tabel voor kunnen maken


Maar dan zou ik toch voor alle velden, waarvan ook maar de mogelijkheid is dat ze door een andere dan jijzelf worden veranderd, een koppeltabel moeten maken? :/
 
Moose -

Moose -

07/01/2013 20:19:55
Quote Anchor link
Ik ben niet een hele grote voorstander van om je tabel velden echt letterlijk op te nemen in je mapper. Wat nou als je een veld wilt toevoegen of aanpassen. Dan moet je op heel veel plekken code gaan aanpassen.

Ook lijkt het me handig om inderdaad elk veld wat eventueel door iemand anders aangepast kan worden, op te slaan in een aparte tabel. Anders blijf je met dit soort dingen zitten. Een andere oplossing zou zijn om alleen maar de velden mee te geven die je wilt aanpassen, maar dan kan je net zo goed de query zelf gaan schrijven

Edit: ik zou voor dit specifieke geval zelfs drie tabellen aanmaken

user, transactie, huidige_munten

transactie heeft een id, een gever, een ontvanger en een amount (plus of min)
user is je model
huidige_munten is een aparte tabel met een userid en een veld met het aantal munten. De enige aanpassingen die je doet op deze tabel is + munten of - munten. Je maakt eerst een transactie aan, en na het aanmaken van de transactie update je ook meteen je huidige_munten tabel. Je mag alleen maar deze tabel aanpassen net nadat er een transactie is aangemaakt. Zo kan het nooit voorkomen dat dit verkeerd wordt aangepast
Gewijzigd op 07/01/2013 20:28:58 door Moose -
 
Lord Gaga

Lord Gaga

07/01/2013 20:37:07
Quote Anchor link
De tabelvelden niet letterlijk opnemen in de map? Op welke andere manier zou ik dit dan moeten doen?

En is het uiteindelijk niet veel makkelijker dat save() alleen de dingen opslaat die zijn aangepast? Volgens mij voorkomt dit een heel hoop gedoe met allerlei omweggetjes via koppeltabellen..
 
Moose -

Moose -

07/01/2013 20:53:09
Quote Anchor link
Koppel tabel is geen omweg, het is de oplossing
 
Lord Gaga

Lord Gaga

08/01/2013 11:46:41
Quote Anchor link
Ik snap niet echt hoe je dit nou precies met een koppeltabel doet, kun je een voorbeeld geven van hoe ik dit zou moeten doen?
 
Moose -

Moose -

08/01/2013 11:58:40
Quote Anchor link
Die heb ik toch gegeven daarboven? Als je het aantal munten gewoon als kolom bij je user tabel neerzet krijg je toch nog steeds problemen dat hij dubbel overschreven kan worden?
 
No One

No One

08/01/2013 12:08:54
Quote Anchor link
Ik moet toch toegeven dat ik het idee van Lord Gaga erg aantrekkelijk vind. waarom een koppeltabel als de koppeltabel alleen de userID gaat bevatten en de aantal coins?? tenzij je een history wilt maken met "transacties": datum - useridfrom - useridto - coins en zo op die manier het huidige aantal coins berekend.

Maar toch, ik kan me voorstellen dat je alleen wilt updaten wat je gewijzigd hebt. dan zou je een mechanisme moeten bedenken die dus bijhoud welke variabelen je gewijzigd hebt...
 
Lord Gaga

Lord Gaga

08/01/2013 12:10:15
Quote Anchor link
Dus dan moet ik munten in een aparte tabel zetten?

@No one:
Inderdaad, als je een update query maakt, pas je toch ook alleen aan wat je wilt aanpassen?
Gewijzigd op 08/01/2013 12:14:00 door Lord Gaga
 

Pagina: 1 2 3 4 volgende »



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.