OOP - Database
Ik ben vrij nieuw wat betreft PHP. Ik heb al diverse tutorials doorgelezen over het object georiënteerd programmeren, en ik begrijp het op zich prima. Het voordeel dat ik heb is dat ik al een aantal jaar C# gebruik, en daar ook al OOP toepas.
Nu zit ik met het volgende probleem, ik heb hier een database staan, waar gebruikers telefoons hebben, op zich geen probleem. Nu heb ik een class die er ongeveer zo uitziet;
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
public class person {
private var $name;
function setName($newName) {
$this->name = $newName;
}
function getName() {
return $this->name;
}
}
private var $name;
function setName($newName) {
$this->name = $newName;
}
function getName() {
return $this->name;
}
}
Op zich is dit vrij logisch denk ik. Nu is het dus zo, dat een persoon meerdere telefoons kan hebben. in C# krijg je dat je dan in het object persoon een field object telefoon in de vorm van een list, overigens is dit niet de mooiste oplossing, maar het gaat even om het principe.
Nu heb ik dit;
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
class telefoon{
var $telefoon;
function setname($newPhone) {
$this->telefoon= $newPhone;
}
function getPhone() {
return $this->telefoon;
}
}
var $telefoon;
function setname($newPhone) {
$this->telefoon= $newPhone;
}
function getPhone() {
return $this->telefoon;
}
}
Alleen wat ik mij nu afvroeg, is het mogelijk om telefoon dan toe te wijzen aan een gebruiker, of wat is hier de beste oplossing voor?
Of zie ik hier iets compleet verkeerd. Misschien nog interessant om te weten, ik maak gebruik van een MSSQL Database.
Gewijzigd op 07/02/2012 20:19:05 door Sander N
Sander N op 07/02/2012 19:10:45:
... Nu is het dus zo, dat een persoon meerdere telefoons kan hebben. in C# krijg je dat je dan in het object persoon een field object telefoon in de vorm van een list...
Ja, zoiets kan je inderdaad doen.
Je kunt inderdaad beide classes behouden (persoon & telefoon)
Wat je dan in de class persoon doet, is een array maken $this->telefoonnummers
Die kan je vullen met objecten van de class telefoon.
Het aanroepen kan er dan zo uitzien
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$m_persoon = new persoon();
$m_persoon->setName('Chuck Norris');
$tel1 = new telefoon();
$tel1->setType('GSM');
$tel1->setNummer('555-...');
$m_persoon->addTelefoon($tel1);
...
class persoon {
...
protected $telefoonnummers = array();
public function addTelefoon($tel) {
$this->telefoonnummers[] = $tel;
}
}
?>
$m_persoon = new persoon();
$m_persoon->setName('Chuck Norris');
$tel1 = new telefoon();
$tel1->setType('GSM');
$tel1->setNummer('555-...');
$m_persoon->addTelefoon($tel1);
...
class persoon {
...
protected $telefoonnummers = array();
public function addTelefoon($tel) {
$this->telefoonnummers[] = $tel;
}
}
?>
Gewijzigd op 07/02/2012 20:27:05 door Kris Peeters
- Classes schrijf je altijd met een hoofdletter
- var voor een $variabele zetten gaat fout, je moet juist voor je $variabele zetten of hij public, private of protected is
Succes!
Gewijzigd op 07/02/2012 21:48:11 door Roel -
Bedankt voor jullie reacties, ik zat nog wat verder op het forum te kijken en kwam erachter dat er nog best wel wat nuttige topics zijn die een andere situatie als mij hebben, maar hetzelfde principe volgens mij, iets over een gastenboek bijvoorbeeld.
Als ik nog vragen heb stel ik ze hier snel,
Thanx!
Tevens gebruik je het keyword 'var', deze komt uit PHP4 en in PHP5 moet je public, protected of private gebruiken, waarbij ik de voorkeur geef aan protected.
Thanks voor je antwoord, het komt er dus op neer dat ik de FETCH_CLASS beter niet kan gebruiken.
Wat betreft de var, ik had een stukje hierboven gekopieerd, waar deze fout nog in stond, maar je hebt wel gelijk!
Bedankt!
Edit;
Nog wel een andere vraag, is het netter om elk object dat je defineerd in een aparte PHP sheet te doen, of is het beter om meerdere classes aan te maken in 1 php sheet?
in C# deed ik namelijke elk object in een nieuwe bestand.
Gewijzigd op 10/02/2012 09:26:28 door Sander N
Niet over indentering, niet over camelCaps tov. underscore ...
Meestal is dat kwestie van smaak.
Vaak wordt die smaak overgeërfd van vroegere programmeerstijlen; ik kom ook van een c/c++/c# achtergrond.
Bekijk het vooral praktisch. Denk dan in de eerste plaats aan herbruikbaarheid.
Als je denkt dat je de class Telefoon nog vaak zal gebruiken, los van Persoon; en dat je die nog zwaar zal uitbreiden ... kan het nuttig zijn die apart te zetten.
Als je het ziet als een onderdeel van Persoon ... kan je ze samen zetten.
Hier is onlangs een tutorial geschreven over classes die afhankelijk zijn van andere classes; misschien staat daar iets interessants op ivm je vraag
Bedankt voor je antwoord, waar kan ik deze tutorial precies vinden?
Sander
http://www.phphulp.nl/php/tutorial/classes/dependency-injection/760/
Ik heb het niet deftig doorgenomen; ik weet niet zeker of het precies een antwoord geeft op je vraag
Wouter J op 10/02/2012 08:59:55:
Tevens gebruik je het keyword 'var', deze komt uit PHP4 en in PHP5 moet je public, protected of private gebruiken, waarbij ik de voorkeur geef aan protected.
Protected voor variabelen? Waarom? Persoonlijk geef ik nagenoeg altijd de voorkeur aan private bij variabelen zodat ook descending objecten via de getter/setter met de variabelen moeten werken. Zo kan ik binnen het object waarin de variabelen worden gedeclareerd ervoor zorgen dat er altijd een juiste waarde in zit.
Ik ben er weer, ik ben weer een stukje verder. Ik heb nu dit;
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private $_idRFIDTool;
private $_pix_Res_Sofi;
public function __construct($params = array()) {
if(isset($params['IdRFIDTool']))
{
echo "Hij is gezet.";
}
//$this -> _idRFIDTool = $params['IdRFIDTool'];
//$this -> _pix_Res_Sofi = $params['Pix_Res_Sofi'];
}
public function GetIdRFID() {
return $this-> _idRFIDTool;
}
private $_pix_Res_Sofi;
public function __construct($params = array()) {
if(isset($params['IdRFIDTool']))
{
echo "Hij is gezet.";
}
//$this -> _idRFIDTool = $params['IdRFIDTool'];
//$this -> _pix_Res_Sofi = $params['Pix_Res_Sofi'];
}
public function GetIdRFID() {
return $this-> _idRFIDTool;
}
Stel ik wil nu een nieuwe tool aan maken door tool = new Tool();. Hoe kan ik nu het beste waardes toewijzen. Ik denk dat ik naast de constructor ook nog aparte setters moet maken, klopt dat?
Of is het beter als ik zo een nieuwe 'Tool' aanmaak?
Weer een edit;
Ik heb nu aparte getters en setters gemaakt, die ik ook weer hergebruik in de construct. Werkt prima volgens mij!
Gewijzigd op 13/02/2012 09:40:56 door Sander N
Je kan inderdaad in de constructor ook de setter functies gebuiken.
Stel dat je in een setter nog extra valideert (bv. zien of de waarde van het juiste type is; zien dat een numerieke waarde binnen de juiste range ligt; ...)
Dan kan je best in de constructor die setter aanroepen; Dan weet je dat die waarde gevalideerd wordt.
----
Nog iets leuks wat je met OOP kan doen: "Method Chaining" (zie ook Google)
Wat je moet doen: elke setter functie eindig je met return $this.
Dan wordt dus het volledige object (na de laatste aanpassing) terug gegeven.
Dat laat je toe om dit te doen:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$telefoon->setNummer('555-31...')
->setType('GSM')
->setNogIets('nog iets');
?>
$telefoon->setNummer('555-31...')
->setType('GSM')
->setNogIets('nog iets');
?>
Aangezien de setter het object teruggeeft, moet je het niet opnieuw aanspreken, maar kan je de setters aan mekaar linken (zoals je schakels van een ketting aan mekaar linkt)
Gewijzigd op 13/02/2012 11:45:49 door Kris Peeters
@Sander, zou je je code tussen <?php tags willen zetten? Dat maakt het wat leesbaarder.
Tevens zou ik alle classes in aparte bestanden zetten. Het include wordt zo stukken simpeler.
@Erwin, daar heb je ook wel weer een punt. Maar ik denk toch dat in veel gevallen het simpeler is om in een child object gewoon $this->propName te gebruiken i.p.v. $this->setPropName().
Ieder zijn voorkeur. Het is niet zo dat ik denk dat het het beste is, maar dat is mijn overweging om private te gebruiken en niet protected. Ik was alleen benieuwd waarom jij voor protected kiest.
Maar je kan zeker gelijk hebben; ik heb geen weet dat dit in php echt zou helpen.
Kijk eens naar MooTools, die is stukken beter qua OO.
@Erwin, even een vraagje. Die setters, maak jij die dan ook public? Stel je hebt een person class met de propertie rank. Maak je dan in die person een setter voor het zetten van die rank, zodat je die in een admin class kan zetten? Iets als dit:
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
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
<?php
abstract class Person
{
private $rank;
public function setRank( $rank )
{
$this->rank = (int) $rank;
}
abstract public function __construct();
}
class Admin extends Person
{
public function __construct()
{
$this->setRank(10);
}
}
class User extends Person
{
public function __construct()
{
$this->setRank(1);
}
}
$bas = new Admin();
$peter = new User();
$peter->setRank(10); // hé, nu heeft user peter opeens admin rechten
?>
abstract class Person
{
private $rank;
public function setRank( $rank )
{
$this->rank = (int) $rank;
}
abstract public function __construct();
}
class Admin extends Person
{
public function __construct()
{
$this->setRank(10);
}
}
class User extends Person
{
public function __construct()
{
$this->setRank(1);
}
}
$bas = new Admin();
$peter = new User();
$peter->setRank(10); // hé, nu heeft user peter opeens admin rechten
?>
Op het moment dat ik nu een resultset ophaal uit de database, zet ik het in een andere class om in 'persoon' objecten.
Dus ik loop het result door, en doe voor elke keer dat je de loop binnen komt .
Dit werkt prima, nu wil ik graag een array hiervan maken, en dat die ik als volgt;
Deze maak ik boven de loop aan, vervolgens doe ik dit in de loop;
Vervolgens wil ik dit graag omzetten met de json_encode methode in PHP, alleen ik krijg telkens een lege JSON string, wat zou hiervan de oorzaak kunnen zijn, of is er een betere manier hiervoor?
Het komt er dus op neer dat ik een lijst van instanties wil omzetten in een stukje JSON code.
Sander
Gewijzigd op 28/02/2012 20:59:56 door Sander N
Sander N op 28/02/2012 20:53:18:
Op het moment dat ik nu een resultset ophaal uit de database, zet ik het in een andere class om in 'persoon' objecten.
Toon eens wat je doet met $personenArray.
Waar sla je dat op?
Toon vooral eens code buiten de class; hoe je de objecten gebruikt
Objecten in PHP kunnen niet worden omgezet naar objecten in JSON met json_encode. Vandaar dat je allemaal lege objecten krijgt.
Code (php)
Vervolgens wordt het result afgehandeld in een pagina dat gaat op deze manier;
Code (php)
Ik hoop dat het zo een stukje duidelijker is. Wat ik dus probeer te bereiken is de Array met personen instanties om te zetten in een stukje JSON. Wat ik me trouwens net zit te bedenken, is het verstandiger om in plaats in de 'manager' de results terug te sturen, een array met personen terug te sturen? Nu maak ik namelijk de personen aan in de loop.
Het enige waar ik dan mee zit, is dat ik die objecten dan niet terug kan sturen in JSON als response.
Toevoeging op 28/02/2012 22:42:48:
Wouter J op 28/02/2012 22:31:09:
Objecten in PHP kunnen niet worden omgezet naar objecten in JSON met json_encode. Vandaar dat je allemaal lege objecten krijgt.
Oke, dus wat ik hier moet doen, is het PDO result omzetten naar JSON, dat lukt namelijk wel.
Gewijzigd op 28/02/2012 22:44:32 door Sander N