Variable uit parent class halen
Ik heb wat lopen rond zoeken op internet maar kan helaas geen goed werkende oplossing vinden. Ik heb namelijk twee classes.
Code (php)
Het probleem is nu dat de constructor van class B een lege array terug geeft terwijl de parent wel degelijk iets in de config array geplaatst heeft.
Iemand een idee hoe ik dit kan oplossen? Of moet ik hierbij verplicht static gaan gebruiken?
Bedankt alvast!
Gewijzigd op 10/02/2013 17:09:58 door Ruben Portier
In PHP wordt de constructor overriden. Je krijgt nu dus alleen de constructor van B en niet meer die van A. Gebruik parent::__construct() om de parent constructor aan te roepen.
Dus als class B de variable config print dan zou je test moeten zien. Dit werkt alleen door een static variable te gebruiken, klopt dit?
Want waar stel je die config property in? Juist ja, in de constructor van A. Wat gebeurd er dus als je in klasse B een constructor maakt? Dan wordt die van A niet meer aangeroepen. En als die van A niet meer aangeroepen wordt blijft de config property dus leeg. En wat gebeurd er als die leeg blijft? Dan zal de var dump in de constructor van B niks tonen.
EDIT: ik leg het even wat beter uit.
Code (php)
Als ik nu volgende code uitvoer zal ik niets terug krijgen:
Als ik echter deze code uitvoer, zal het wel lukken:
Gewijzigd op 10/02/2013 19:21:38 door Ruben Portier
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 A {
protected $var;
public function set() {
$this->var = 'boe';
}
public function get() {
return $this->var;
}
}
class B
{
private $a;
public function setA(A $a)
{
$this->a = $a;
}
public function get()
{
return $this->a->get();
}
}
$a = new A();
$b = new B();
$b->seta($a);
$a->set();
$b->get(); // >> 'boe'
?>
class A {
protected $var;
public function set() {
$this->var = 'boe';
}
public function get() {
return $this->var;
}
}
class B
{
private $a;
public function setA(A $a)
{
$this->a = $a;
}
public function get()
{
return $this->a->get();
}
}
$a = new A();
$b = new B();
$b->seta($a);
$a->set();
$b->get(); // >> 'boe'
?>
Tevens kunnen die protecteds bij die methodes ook helemaal niet. Misschien goed om eens de basis te leren: http://phptuts.nl/view/45/
Volgens mij kan je toch echt wel protecten function gebruiken?
Via jouw bron:
Voorbeelden van correcte method namen:
public function filterInput()
public function draw()
protected function _calculateTotal()
private function _countMessages()
Ja, maar dan kun je ze niet meer aanroepen op de manier zoals jij nu liet zien.
Daarnaast vraag ik me af hoe ik dus eigenlijk het volgende kan doen:
Code (php)
Dus eigenlijk heb ik een database class. In de main class wordt de databaseconnectie aangemaakt. Wat ik dan wil is dat de child user ook aan die database kan d.m.v. $this->db. Dit lukt me telkens niet. En ik wil niet $this->db doorsturen naar de user's constructor, dat ziet er echt niet 'proper' uit.
Singleton is ook niet goed? Kan je mij uitleggen waarom precies? Overal lees je verschillende verhalen.
Gewijzigd op 10/02/2013 20:39:02 door Ruben Portier
Een user class extenden van een database class (jij noemt hem main) is niet logisch.
Een class administrator extenden van een user is wel logisch. een administrator is namelijk ook een user maar dan één met wat extra privileges.
Je zou het dus beter iets anders kunnen doen. (hoe daar zullen de meningen vast weer over uiteenlopen)
Maar toch een mogelijk idee.
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
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
<?php
class Database {
private $db;
function __constructor() {
$this->dbConnect();
}
public function dbConnect() {
$this->db = new mysqli($host, $user, $pass, $dbname);
}
}
class User {
private $db;
private $username;
// en zo nog meer
function __constructor($db, $userid) {
$this->db = $db;
// run query to retrieve user information with $userid
}
function logIn() {
$this->db->query('SELECT * FROM users');
// en zo nog meer
}
}
class Main {
private $db;
function __constructor() {
$this->db = new $db();
$user = new User($this->db, 1);
$user->logIn();
}
}
new Main();
?>
class Database {
private $db;
function __constructor() {
$this->dbConnect();
}
public function dbConnect() {
$this->db = new mysqli($host, $user, $pass, $dbname);
}
}
class User {
private $db;
private $username;
// en zo nog meer
function __constructor($db, $userid) {
$this->db = $db;
// run query to retrieve user information with $userid
}
function logIn() {
$this->db->query('SELECT * FROM users');
// en zo nog meer
}
}
class Main {
private $db;
function __constructor() {
$this->db = new $db();
$user = new User($this->db, 1);
$user->logIn();
}
}
new Main();
?>
De controller class extend op de system class, zelfde voor model, database enz. De controller class dient bv. om controllers mee te laden, de model class om models te laden, de database dient dan weer om een database connectie te maken.
Mijn vraag is nu, hoe kan een controller die geladen wordt door de controller class (de controller die geladen wordt extend op de controller class, die dan weer extend op de system class) de database class gaan gebruiken (die extend op de system class).
Ik heb al naar dergelijke frameworks gekeken en sommigen gebruiken Singleton. Ik weet niet of dit zo'n goed idee is. Het zou toch ook anders moeten kunnen?
Bedankt alvast!
(maar dit is het eerste topic dat ik van je lees) denk jij nu nog veel te makkelijk over OO. Al die extends zijn namelijk compleet verkeerd. Ik raad je aan eerst eens goed naar OO principes te kijken, en dan niet alleen naar OO syntax tutorials, en dan kun je over een half jaar misschien nog eens nadenken over het zelf maken van een framework.
Ruben, naar mijn mening Wat ik wel zou kunnen doen is telkens waar ik de database nodig heb het volgende commando uit te voeren:
Maar hoe kan ik dan maken dat je de database kan aanroepen via $this->db? Dus ik laad hem met een load-functie die in de parent class staat. Die maakt dan een nieuw database-object aan op $this->db. Maar kan de child dan ook aan die database komen? Of zal die ook leeg zijn?
Quote:
Telkens begin ik opnieuw omdat ik het op een andere manier wil gaan bouwen.
En precies om deze rede raad ik je dus aan om eerst eens goede OO denk tutorials te lezen. Je begint telkens opnieuw, omdat iets mooiers in gedachte had. Wat je bij OO juist doet is dat je de eerste 2 maanden je computer niet aanzet en je alleen je project gaat uitschrijven, totdat je echt alles hebt zoals jij het wilt.
En als je OO wilt leren zou ik zeker niet met een framework beginnen. Werelds grootste OO en PHP experts doen er alsnog met 100 man een jaar over om een framework te onderhouden en enkele kleine nieuwe dingen eraan toe te voegen. Frameworks zijn de meest ingewikkelde systemen die je in PHP ooit gaat maken. Frameworks kun je alleen beginnen als je OO principes en design pattern volledig hebt begrepen en jaren ervaring er mee hebt.
Er zijn hier al meerdere forumleden aan frameworks begonnen en het is leuk dat ze het doen, maar daar blijft het ook wel bij. Ze hebben deze projecten al meerdere malen opnieuw opgestart en of ze ooit hun framework afkrijgen stel ik ter discussie.
Gewijzigd op 10/02/2013 23:18:57 door Wouter J
Wouter J op 10/02/2013 17:38:09:
In PHP wordt de constructor overriden. Je krijgt nu dus alleen de constructor van B en niet meer die van A. Gebruik parent::__construct() om de parent constructor aan te roepen.
Niet alleen in PHP hoor wouter :)
@TS
Volgens mij wil jij het volgende
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
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
<?php
class A {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
?
en dan de child klasse aanmaken
[code]<?php
class B extends A {
public function __construct($name) {
parent::__construct($name);
}
}
?>
Wat je dan doet om via class B de methode aan te roepen die je in de parent class hebt staan is
<?php
$b = new B('Batman');
echo 'Ik heet ' . $b->getName();
?>
Als je in class B een nieuwe constructor zou maken ( zonder parent::__construct();) zou deze de constructor van A overriden
class A {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
?
en dan de child klasse aanmaken
[code]<?php
class B extends A {
public function __construct($name) {
parent::__construct($name);
}
}
?>
Wat je dan doet om via class B de methode aan te roepen die je in de parent class hebt staan is
<?php
$b = new B('Batman');
echo 'Ik heet ' . $b->getName();
?>
Als je in class B een nieuwe constructor zou maken ( zonder parent::__construct();) zou deze de constructor van A overriden