connectie met db - procedueel of OOP in professionele wereld?
2) Indien via OOP: is dat dan met een controllerbetand, business/service bestand, databastand, entiteitbestand en betand met de login gegevens? Of is een verkort trajact een meer gebruikte manier van werken?
Gewijzigd op 25/02/2016 21:06:00 door Tom Van de Velde
De meeste professionals gebruiken vaak de OO-techniek. Deze is mooi te combineren met classes en dergelijke. Zo heb ik ook meteen foutafhandeling in $db->query() geschreven met een simpele extend.
Momenteel ging ik zo te werk:
ik heb een 'controller' die een view include (zeg maar het design)
Vanuit deze controller raadpleeg ik de service (met bijhorende getter)
Vanuit de service ga ik naar datalaag
In de datalaag voer ik de sql uit en steek ik de resultaten in een klasse.
Is dit een goede manier van werken?
Of is het meer gebruikelijk om mijn'service' laag er tussenuit te laten?
Ik ben echt benieuwd naar hoe andere het doen, maar vind er maar weinig over terug.
MVC. Wat voor mij wel vast staat is dat professionals met OOP werken.
op vraag 2 zou ik willen zeggen dat de werkelijke wereld wat complexer is. Feitelijk begint het met een front controller, een request (object) en een kernel. Dan wordt er een passende route gezocht en pas als bekend is welke route (lees URI) de gebruiker opvraagt dan wordt de controller die daar bij past aangeroepen. Beveiliging moet dan bij dit alles nog eens op nummer één staan. (Welke controller mag aangeroepen worden en in welke request-method mag dat dan?) Sommige controllers mogen alleen aangeroepen worden als je bent ingelogd en dan ook nog eens over voldoende rechten beschikt.
Een bestand met login-gegevens kan maar zal in 90% van de gevallen in een database staan in plaats van in een bestand. Een verkort traject is voor een pro niet de manier van werken.
Hoe kom je aan de naam entiteitbestand? Kun jij uitleggen wat een entity (hou het liever in het engels) is?
Als ik je goed begrijp Tom dan zou jouw manier van werken niet verkeerd zijn maar het is natuurlijk nog erg globaal. Ik heb je code nog niet gezien en ik weet dus niet van welke technieken je gebruikmaakt. Jouw beschrijving lijkt iig erg op op vraag 2 zou ik willen zeggen dat de werkelijke wereld wat complexer is. Feitelijk begint het met een front controller, een request (object) en een kernel. Dan wordt er een passende route gezocht en pas als bekend is welke route (lees URI) de gebruiker opvraagt dan wordt de controller die daar bij past aangeroepen. Beveiliging moet dan bij dit alles nog eens op nummer één staan. (Welke controller mag aangeroepen worden en in welke request-method mag dat dan?) Sommige controllers mogen alleen aangeroepen worden als je bent ingelogd en dan ook nog eens over voldoende rechten beschikt.
Een bestand met login-gegevens kan maar zal in 90% van de gevallen in een database staan in plaats van in een bestand. Een verkort traject is voor een pro niet de manier van werken.
Hoe kom je aan de naam entiteitbestand? Kun jij uitleggen wat een entity (hou het liever in het engels) is?
Gewijzigd op 26/02/2016 00:37:54 door Frank Nietbelangrijk
Het is inderdaad via MVC dat ik het nu doe.
Valt MVC dan nog niet onder OOP?
Onder mijn entiteiten vallen mijn klassen. Het is een soort van object waaraan ik kenmerken mee geef.
bv persoon heeft een lengte, gewicht, haarkleur, kleur ogen, ....
als setter gebruik ik een constructor en de getters doe ik per property.
Ik werk met een genormaliseerde database, maar stel dat ik de database gedeeltelijk genormaliseer - dan zouden heel wat entiteiten overeenkomen met de 'hooftabellen' van men database.
Indien MVC niet onder OOP voor php valt, is OOP voor PHP ergens goed uitgelegd online? Liefst met veel voorbeelden :-)
OOP staat voor object oriented programming. ofwel object georiënteerd programmeren. Dit doe je door een aantal technieken toe te passen maar ook door objecten te creëren met classes die te vergelijken zijn met objecten in het dagelijks leven. Zo een object is bijvoorbeeld een gebruiker of User maar ook een PDF-Creator wat in het dagelijks leven een broodbakmachine zou kunnen zijn. Het zijn dingen die bepaalde eigenschappen hebben en die over het algemeen maar één functie (of verantwoordelijkheid) hebben. Denk maar na: als jij een broodbakmachine gaat ontwerpen die ook nog eens kan stofzuigen dan begrijpt de rest van de wereld je niet meer :p.
Deze objecten zijn onder te verdelen in data objecten (ook wel entities genoemd) en functionele objecten. Een User object is bijvoorbeeld een data object. Data objects hebben getters en setters die een stukje data accepteren of teruggeven
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
interface UserInterface // gebruik interfaces zodat je later User classes kunt maken die aan de interface voldoen maar uitgebreider zijn dan deze minimale class.
{
public function getUsername();
public function setUsername($username);
public function getEmail();
public function setEmail($email);
}
?>
interface UserInterface // gebruik interfaces zodat je later User classes kunt maken die aan de interface voldoen maar uitgebreider zijn dan deze minimale class.
{
public function getUsername();
public function setUsername($username);
public function getEmail();
public function setEmail($email);
}
?>
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
class User implements UserInterface // onze eerste data class
{
private username;
private email;
public function getUsername()
return fcfirst($this->username);
}
public function setUsername($username)
{
$this->username = $username;
return $this; // method chaining
}
public function getEmail()
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
return $this; // method chaining
}
// ...
}
?>
class User implements UserInterface // onze eerste data class
{
private username;
private email;
public function getUsername()
return fcfirst($this->username);
}
public function setUsername($username)
{
$this->username = $username;
return $this; // method chaining
}
public function getEmail()
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
return $this; // method chaining
}
// ...
}
?>
Functionele objecten zijn objecten die iets gaan afhandelen voor je:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
class PDFCreator // onze eerste functionele class
{
private $user;
function __construct(UserInterface $user) // Dependency Injection techniek
{
$this->user = $user;
}
public function create()
{
// normaal wordt hier een pdf bestand in elkaar gezet maar nu even een string om het eenvoudig te houden.
return 'this functions creates a PDF file for user: ' . $this->user->getUsername(); // veilig gebruik van de getUsername() method omdat deze in de interface opgenomen is en dus in elke afgeleide class aanwezig moet zijn ..
}
}
?>
class PDFCreator // onze eerste functionele class
{
private $user;
function __construct(UserInterface $user) // Dependency Injection techniek
{
$this->user = $user;
}
public function create()
{
// normaal wordt hier een pdf bestand in elkaar gezet maar nu even een string om het eenvoudig te houden.
return 'this functions creates a PDF file for user: ' . $this->user->getUsername(); // veilig gebruik van de getUsername() method omdat deze in de interface opgenomen is en dus in elke afgeleide class aanwezig moet zijn ..
}
}
?>
Toevoeging op 27/02/2016 01:02:18:
Laten we eens een andere User class maken:
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
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
<?php
class Admin implements UserInterface
{
private username;
private email;
public function getUsername()
return fcfirst($this->username);
}
public function setUsername($username)
{
$this->username = $username;
return $this; // method chaining
}
public function getEmail()
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
return $this; // method chaining
}
public function isAdmin()
return TRUE;
}
// ...
}
?>
class Admin implements UserInterface
{
private username;
private email;
public function getUsername()
return fcfirst($this->username);
}
public function setUsername($username)
{
$this->username = $username;
return $this; // method chaining
}
public function getEmail()
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
return $this; // method chaining
}
public function isAdmin()
return TRUE;
}
// ...
}
?>
Deze class is ook een afgeleide van UserInterface en kan en mag dus ook aan de PDFCreator meegegeven worden:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<?php
$user = new Admin();
$user->setUsername('Tom');
$creator = new PDFCreator($user);
echo $creator->create();
?>
$user = new Admin();
$user->setUsername('Tom');
$creator = new PDFCreator($user);
echo $creator->create();
?>
Toevoeging op 27/02/2016 01:07:27:
OOP voor beginners: http://www.phptuts.nl/view/45/
Gewijzigd op 27/02/2016 01:09:43 door Frank Nietbelangrijk
Alleen was ik ook benieuwd hoe jullie de db-connectie maken. Maar dat leer ik misschien zodadelijk via de link :)
Een super-summier voorbeeldje hoe je je OOP applicatie zou kunnen beginnen.
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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
<?php
class ServiceContainer { // De service container bewaard een aantal classes die je veelvuldig gebruikt en makkelijk wilt raadplegen.
private: $services; // Deze classes noemt men ook wel services
public function __construct()
{
$this->add('config', new Config()); // een Config class die al je configuratie-instellingen kan lezen
$this->add('database', new Database()); // een Database class
$this->add('session', new Session()); // een Session class om van en naar de session te lezen of te schrijven
// ...
}
public function add($name, $instance) // voeg een service toe aan de services array
{
$this->services[$name] = $instance;
}
public function get($name) // verkrijg een service door de naam op te geven
{
if(isset($this->services[$name]))
return $this->services[$name];
return FALSE;
}
}
class Kernel { // De eerste class die geinstantieerd wordt. Tevens de enige class die vanaf de global-space instantieert.
private $container;
public function __construct()
{
$this->container = new ServiceContainer(); // Maak de servicecontainer aan
$this->router = new Router(); // Maak de router aan. De router gaat bepalen welke actie genomen moet worden en roept dan een controller aan.
} // bijvoorbeeld: indexAction, aboutAction of contactAction. (Lees iets over MVC)
public function getContainer()
{
return $this->container;
}
}
class Database {
private $container;
private $mysqli;
public function __construct()
{
$this->container = $GLOBALS['kernel']->getContainer(); // Als eerste moeten we de instantie van de servicecontainer hebben zodat we de Config class kunnen raadplegen.
$config = $this->container->get('config');
$this->mysqli = new mysqli( // Dan kunnen we vervolgens de database instellingen uitlezen en een connectie maken met de database.
$config->getParameter('database_host'),
$config->getParameter('database_user'),
$config->getParameter('database_password'),
$config->getParameter('database_db')
);
if ($mysqli->connect_error) {
throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}
}
public function query($sql) // een functie die als tussenlaag functioneert tussen programmalaag en database.
{ // (je mag geen mysqli* functies gebruiken buiten deze DB class !!!)
return $this->mysqli->query($sql);
}
// ... // nog meer functies zoals num_rows() en getError() etc etc.
}
$kernel = new Kernel(); // hier start je Applicatie en dit is tevens de enige regel op de global space !
?>
class ServiceContainer { // De service container bewaard een aantal classes die je veelvuldig gebruikt en makkelijk wilt raadplegen.
private: $services; // Deze classes noemt men ook wel services
public function __construct()
{
$this->add('config', new Config()); // een Config class die al je configuratie-instellingen kan lezen
$this->add('database', new Database()); // een Database class
$this->add('session', new Session()); // een Session class om van en naar de session te lezen of te schrijven
// ...
}
public function add($name, $instance) // voeg een service toe aan de services array
{
$this->services[$name] = $instance;
}
public function get($name) // verkrijg een service door de naam op te geven
{
if(isset($this->services[$name]))
return $this->services[$name];
return FALSE;
}
}
class Kernel { // De eerste class die geinstantieerd wordt. Tevens de enige class die vanaf de global-space instantieert.
private $container;
public function __construct()
{
$this->container = new ServiceContainer(); // Maak de servicecontainer aan
$this->router = new Router(); // Maak de router aan. De router gaat bepalen welke actie genomen moet worden en roept dan een controller aan.
} // bijvoorbeeld: indexAction, aboutAction of contactAction. (Lees iets over MVC)
public function getContainer()
{
return $this->container;
}
}
class Database {
private $container;
private $mysqli;
public function __construct()
{
$this->container = $GLOBALS['kernel']->getContainer(); // Als eerste moeten we de instantie van de servicecontainer hebben zodat we de Config class kunnen raadplegen.
$config = $this->container->get('config');
$this->mysqli = new mysqli( // Dan kunnen we vervolgens de database instellingen uitlezen en een connectie maken met de database.
$config->getParameter('database_host'),
$config->getParameter('database_user'),
$config->getParameter('database_password'),
$config->getParameter('database_db')
);
if ($mysqli->connect_error) {
throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}
}
public function query($sql) // een functie die als tussenlaag functioneert tussen programmalaag en database.
{ // (je mag geen mysqli* functies gebruiken buiten deze DB class !!!)
return $this->mysqli->query($sql);
}
// ... // nog meer functies zoals num_rows() en getError() etc etc.
}
$kernel = new Kernel(); // hier start je Applicatie en dit is tevens de enige regel op de global space !
?>
Kernel
De startmotor van je applicatie (zie voorbeeld boven)
Router
Bepaalt bij welke uri (deel van url) je naar welke controller en action gaat.
Bijvoorbeeld deze url: www.mijnsite.nl/contact --> laadt de ContactController en de indexAction
ContactController: Dit is gewoon een class.
indexAction: Dit is een method (functie) in de ContactController Class
Controller
Hier ga je data verzamelen (bijvoorbeeld uit de database) en roep je een view aan.
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
class ContactController extends Controller
{
public function indexAction()
{
$repo = new ContactRepository();
// haal wat keuzemogelijkheden uit de database die je in een dropdown wilt weergeven in je contactformulier.
$choices = $repo->getContactFormSubjectChoices();
// geef de data mee aan de de view.
return $this->render('contact/index.html.php', array('choices' => $choices));
}
}
?>
class ContactController extends Controller
{
public function indexAction()
{
$repo = new ContactRepository();
// haal wat keuzemogelijkheden uit de database die je in een dropdown wilt weergeven in je contactformulier.
$choices = $repo->getContactFormSubjectChoices();
// geef de data mee aan de de view.
return $this->render('contact/index.html.php', array('choices' => $choices));
}
}
?>
Repository
Hier staan je queries
Code (php)
View
Dit is je template of html bestand:
Code (php)
Toevoeging op 09/03/2016 23:33:50:
Natuurlijk maak je een logische directory structuur aan voor al deze classes:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
project
|-configuration
|-controller
|-repository
|-system
|-view
|-default
|-contact
|-admin
|-configuration
|-controller
|-repository
|-system
|-view
|-default
|-contact
|-admin
En al snel kom je er achter dat een framework als Yii, codeigniter, Laravel of (mijn favo) Symfony handig zou zijn. Dan kun je jezelf weer richten op het echte werk: een toffe website bouwen :-)
Gewijzigd op 09/03/2016 23:24:55 door Frank Nietbelangrijk