Variable van parrent class aanroepen
hey mensen,
ik heb 3 classes
ik heb dus een variable in de hoofdclass
nu wil ik de waarde van die variable die ik heb geset gebruiken voor elke child
dus als ik in de andere classes $this->var1 gebruik werkt dat niet
ik moet ze altijd setten in de child zelf
hoe kan ik dat aanpakken dat ik die enkel kan setten in main class en dan verwijzen naar de $var1 in main class?
ik heb 3 classes
Code (php)
ik heb dus een variable in de hoofdclass
nu wil ik de waarde van die variable die ik heb geset gebruiken voor elke child
dus als ik in de andere classes $this->var1 gebruik werkt dat niet
ik moet ze altijd setten in de child zelf
hoe kan ik dat aanpakken dat ik die enkel kan setten in main class en dan verwijzen naar de $var1 in main class?
Dat kan niet. De drie instanties zijn drie op zichzelf staande objecten, met hun eigen stukje geheugen en hun eigen waardes voor de variabelen.
Als je wil dat bepaalde gegevens altijd in een object geset worden dan moet je dat doen via een factory of service container die bij het aanmaken de properties set.
Als je wil dat bepaalde gegevens altijd in een object geset worden dan moet je dat doen via een factory of service container die bij het aanmaken de properties set.
voor twitter heb je aantal keys nodig voor te authen
nu wil ik dat ik 1 x de keys set in het begin
en dat elke class die kan gebruiken voor te authen.
nu ik per class die keys appart setten maar die zijn dezelfde.
kan je me opweg helpen?
nu wil ik dat ik 1 x de keys set in het begin
en dat elke class die kan gebruiken voor te authen.
nu ik per class die keys appart setten maar die zijn dezelfde.
kan je me opweg helpen?
Als je drie instanties van je class hebt, dan zal je linksom of rechtsom drie keer die gegevens moeten injecteren. Tenzij je het hardcoded in de constructor doet, maar dat lijkt me een zeer slecht idee, want dan kan je het nooit meer voor een andere applicatie met andere Twitter keys gebruiken.
Dus of injecteert het in een property, of je injecteert het via de constructor, of je maakt een config object (met daarin de keys, de secrets, de service urls etc) en injecteert dat object. Maar hoe dan ook zal je dat voor elke instantie moeten doen.
Dus of injecteert het in een property, of je injecteert het via de constructor, of je maakt een config object (met daarin de keys, de secrets, de service urls etc) en injecteert dat object. Maar hoe dan ook zal je dat voor elke instantie moeten doen.
agja mss is het ook wel logisch dat elke instantie zijn keys moet setten, wie weet heb je ooit eens een situatie dat bv twitterstream clas andere keys heeft dan de tweet opzich.
het is inderdaad ook de bedoeling code te re-usen. dus ik laat het zo
thx
het is inderdaad ook de bedoeling code te re-usen. dus ik laat het zo
thx
ik denk dat ik zo iets zou doen maar ik zou van bijv. Erwin wel eens willen weten of hij dit zo bedoeld.
config.class.php:
twitter.class.php:
config.class.php:
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
class Config {
var $twitter_auth_key = 123456789;
var ...
};
$config = new Config();
?>
class Config {
var $twitter_auth_key = 123456789;
var ...
};
$config = new Config();
?>
twitter.class.php:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
<?php
include_once 'config.class.php';
class twitter_oauth{
public $var1;
__construct($config) {
$this->var1 = $config->twitter_auth_key;
}
};
?>
include_once 'config.class.php';
class twitter_oauth{
public $var1;
__construct($config) {
$this->var1 = $config->twitter_auth_key;
}
};
?>
Gewijzigd op 12/06/2013 16:35:25 door Frank Nietbelangrijk
Nooit public of var in je objecten gebruiken(!)
Verder denk ik dat dat erwin's idee is.
Ik zou de DI container gebruiken:
Verder denk ik dat dat erwin's idee is.
Ik zou de DI container gebruiken:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
class Twitter_OAuth
{
private $apiKey;
public function __construct($key)
{
$this->apiKey = $key;
}
}
$container->set('twitter.api_key', 'adgy319ygda976g2q');
$container->set('twitter.oauth.class', 'Twitter_OAuth');
$container->set('twitter.oauth', function ($c) {
return new ($c->get('twitter.oauth_class'))($c->get('twitter.api_key'));
});
// in gebruik:
$oauth = $container->get('twitter.oauth');
?>
class Twitter_OAuth
{
private $apiKey;
public function __construct($key)
{
$this->apiKey = $key;
}
}
$container->set('twitter.api_key', 'adgy319ygda976g2q');
$container->set('twitter.oauth.class', 'Twitter_OAuth');
$container->set('twitter.oauth', function ($c) {
return new ($c->get('twitter.oauth_class'))($c->get('twitter.api_key'));
});
// in gebruik:
$oauth = $container->get('twitter.oauth');
?>
Dat is inderdaad ook hoe ik het heb. Met in dat config object dan ook nog de urls, de secrets en de tokens.
Dit config object zal je dan wel bij elke nieuwe instantie die je aanmaakt moeten injecteren (zoals je nu doet in de constructor). Op zich hoef je dan maar op 1 plek de gegevens te hebben, namelijk op de plek waar je dat config object aanmaakt, maar het config object blijf je drie keer injecteren. Daar ontkom je niet aan.
Enige is dat ik niet de gegevens hardcoded in het config object heb, maar dat terzijde.
Dit config object zal je dan wel bij elke nieuwe instantie die je aanmaakt moeten injecteren (zoals je nu doet in de constructor). Op zich hoef je dan maar op 1 plek de gegevens te hebben, namelijk op de plek waar je dat config object aanmaakt, maar het config object blijf je drie keer injecteren. Daar ontkom je niet aan.
Enige is dat ik niet de gegevens hardcoded in het config object heb, maar dat terzijde.
@wouter: Ik ben het op zich eens met de stelling dat properties niet publiek moeten zijn maar ik dacht dat het voor die config niet zo een vaart zou lopen. Maar je hebt gelijk. Die container is een symfony object? en hoe ziet een simpele vorm van die klas er uit?
@erwin: waar bewaar jij je config-gegevens dan?
Bedankt voor de reacties. Frank.
@erwin: waar bewaar jij je config-gegevens dan?
Bedankt voor de reacties. Frank.
Die config gegevens moeten door de applicatie ingegeven worden. Dat kan uit een database komen, kan uit een applicatie config object komen, kan ook in hardcoded applicatie constante zitten.
Mijn Oauth config class is een algemene class die dus niet applicatie specifieke gegevens in zich heeft zitten.
Mijn Oauth config class is een algemene class die dus niet applicatie specifieke gegevens in zich heeft zitten.
Frank, nee die Container is gewoon een container klasse. Hoeft niet perse die van Symfony te zijn (die heeft overigens ook een ander interface dan ik nu toonde).
Een paar voorbeelden van containers:
- https://github.com/fabpot/pimple
- https://github.com/WouterJ/dic
- http://symfony.com/doc/current/components/dependency_injection/introduction.html
Een paar voorbeelden van containers:
- https://github.com/fabpot/pimple
- https://github.com/WouterJ/dic
- http://symfony.com/doc/current/components/dependency_injection/introduction.html
@Wouter,
Ik begrijp niet waarom een object geen public properties zou mogen bevatten, als je jouw werkwijze met get en set volgt. Want dan zijn ze net zo public.
Ik begrijp niet waarom een object geen public properties zou mogen bevatten, als je jouw werkwijze met get en set volgt. Want dan zijn ze net zo public.
Ger, je hebt dan grip op het setten en getten. Nu is het misschien allemaal straightforward, allewel er al een check in zit of de setting al bestaat, maar misschien dat ik dat straks wel anders wil doen. Dan moet naar mijn mening de interface hetzelfde blijven, maar de code erachter anders. Met public properties beperk je jezelf enorm, je bent gebonden aan die oncontroleerbare public property en alleen met een BC break kun je dat veranderen.
Het is ook niet zo dat ik het geheel met je oneens ben, maar met een get(property) in je object worden al je private vars gewoon public (of zie ik iets verkeerd?)
En dan vind je redenering dat je nooit public properties mag hebben niet logisch.
En dan vind je redenering dat je nooit public properties mag hebben niet logisch.
Ja, het is nu public. Maar OO gaat voor namelijk ook over 'in de toekomst'. Mocht ik in de toekomst checks willen doen en meer controle willen hebben op mijn settings array dan kan ik zo even chapchap de get method aanpassen en klaar is kees.
Echter als je public properties gebruikt moet je eerst die get method aanmaken en vervolgens al je code aanpassen om de get method te gebruiken en dat gaat naar mijn mening tegen de OO principes in.
Dat is ook precies de rede dat ik de regel heb dat alleen getters en setters toegang hebben tot de properties. De rest moet allemaal de getters en setters gebruiken, zelfs al is het dezelfde klasse.
Echter als je public properties gebruikt moet je eerst die get method aanmaken en vervolgens al je code aanpassen om de get method te gebruiken en dat gaat naar mijn mening tegen de OO principes in.
Dat is ook precies de rede dat ik de regel heb dat alleen getters en setters toegang hebben tot de properties. De rest moet allemaal de getters en setters gebruiken, zelfs al is het dezelfde klasse.
Gewijzigd op 12/06/2013 19:33:15 door Wouter J
Ger van Steenderen op 12/06/2013 19:28:27:
En dan vind je redenering dat je nooit public properties mag hebben niet logisch.
Ik zal het je nog sterker vertellen: nooit public properties en nooit protected properties.
Bekijk het eens anders. Een class is verantwoordelijk voor alles wat er binnen die class gebeurt. Als een ander deel van de applicatie vraagt om een waarde, dan moet die class ervoor zorgen dat die iets nuttigs teruggeeft. Dat wordt erg lastig op het moment dat andere delen van de applicatie in de interne data van die class kan gaan zitten vroeten. Dan zal die class dus elke keer moeten checken of de data nog wel is wat het was. Maar nog erger, als een ander deel van de applicatie rechtstreeks een property kan uitlezen dan weet de class daar niet eens iets van en kan dus zelfs de check niet uitgevoerd worden.
Vergelijk het nu eens met een database beheerder die verantwoordelijk is voor de hele database omgeving van een bedrijf. Als er iets mis is met de databases dan is die man de klos. Denk je dat die man iedereen nu rechtstreeks lees en schrijf rechten op de database gaat geven? Ik denk het niet....
Gewijzigd op 12/06/2013 19:43:58 door Erwin H
Ik zie niet in waarom dat tegen de OO principes in zou gaan.
Heeft veel meer te maken met de combinatie PHP en OO!
Heeft veel meer te maken met de combinatie PHP en OO!
Erwin H op 12/06/2013 17:27:59:
Die config gegevens moeten door de applicatie ingegeven worden. Dat kan uit een database komen, kan uit een applicatie config object komen, kan ook in hardcoded applicatie constante zitten.
Mijn Oauth config class is een algemene class die dus niet applicatie specifieke gegevens in zich heeft zitten.
Mijn Oauth config class is een algemene class die dus niet applicatie specifieke gegevens in zich heeft zitten.
euhm een config object die zijn gegevens uit de applicatie config object haalt??
en uit de database ja, maar niet alles. om de database te benaderen heb je ook een configuratie nodig. (user, pass, host, db)
Okee jij maakt een verschil tussen applicatie configuration en de configuratie voor één of andere class.
Natuurlijk moet je dat verschil maken, maar dat is het punt niet.
Als je via een config een bepaalde variabele kunt instellen is ie net zo public als je gewoon een public property aanduidt.
Dus, ik begrijp nog steeds die opmerkingen van Erwin en Wouter niet helemaal.
Ik zie in ieder geval het nut niet het niet van:
$this->setName('Ger')
of
$this->name='Ger'
Als je via een config een bepaalde variabele kunt instellen is ie net zo public als je gewoon een public property aanduidt.
Dus, ik begrijp nog steeds die opmerkingen van Erwin en Wouter niet helemaal.
Ik zie in ieder geval het nut niet het niet van:
$this->setName('Ger')
of
$this->name='Ger'
Gewijzigd op 12/06/2013 23:12:29 door Ger van Steenderen
Normalisatie:
Controle:
Deprecate handling:
Een user klasse had eerst een age property, maar dat is vervangen door een birthday property. Met getters kun je voor een tijdelijke oplossing zorgen, zodat de applicatie goed werkt, en tegelijkertijd meld je de user dat hij zijn script moet aanpassen.
Code (php)
Controle:
Code (php)
Deprecate handling:
Een user klasse had eerst een age property, maar dat is vervangen door een birthday property. Met getters kun je voor een tijdelijke oplossing zorgen, zodat de applicatie goed werkt, en tegelijkertijd meld je de user dat hij zijn script moet aanpassen.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class User
{
private $birthday;
public function getAge()
{
trigger_error('Use::getAge is deprecated, use getBirthday instead', E_USER_DEPRECATION);
return date_diff($this->birthday, 'now');
}
}
?>
class User
{
private $birthday;
public function getAge()
{
trigger_error('Use::getAge is deprecated, use getBirthday instead', E_USER_DEPRECATION);
return date_diff($this->birthday, 'now');
}
}
?>
Frank Nietbelangrijk op 12/06/2013 22:06:24:
euhm een config object die zijn gegevens uit de applicatie config object haalt??
en uit de database ja, maar niet alles. om de database te benaderen heb je ook een configuratie nodig. (user, pass, host, db)
Okee jij maakt een verschil tussen applicatie configuration en de configuratie voor één of andere class.
en uit de database ja, maar niet alles. om de database te benaderen heb je ook een configuratie nodig. (user, pass, host, db)
Okee jij maakt een verschil tussen applicatie configuration en de configuratie voor één of andere class.
Krijgt niet haalt. Mijn Oauth config klasse krijgt de gegevens vanuit de applicatie, maar heeft zelf geen weet waar die vandaan komen. Mijn Oauth config klasse heeft dus ook geen database connectie nodig, want die werkt daar verder niet mee. Juist daarom heb ik dat gesplitst. De Oauth config klasse is applicatie onafhankelijk. In de constructor krijgt het de gegevens geinjecteerd. Binnen de applicatie mag het dan best ergens hardcoded staan, want die klassen zijn applicatie specifiek en hoef ik dus niet te kunnen hergebruiken.
Ger van Steenderen op 12/06/2013 23:09:37:
Ik zie in ieder geval het nut niet het niet van:
$this->setName('Ger')
of
$this->name='Ger'
$this->setName('Ger')
of
$this->name='Ger'
Dit is nu binnen de klasse, terwijl het voornamelijk om toegang van buiten een klasse gaat.
Het verschil is de controle. In het eerste geval heeft de klasse geen controle over wat er geplaatst wordt en uitgelezen wordt. Er kunnen dus geen checks plaatsvinden en er kunnen geen andere acties afgehandeld worden.
In het tweede geval heeft de klasse volledige controle. Het kan waardes veranderen, weigeren of exceptions gooien als er iets niet klopt. Daarmee kan de klasse zelf volledig zelfstandig zorg dragen voor de consistentie van de data.
Zelfs als het nu helemaal niet nodig 'lijkt' is het verstandig. In de eerste plaats vanwege toekomst. Het je setters en getters kan je checks later eenvoudig toevoegen. heb je publieke properties dan zal je al je code door moeten om te vinden waar die aangesproken worden en dat veranderen. Maar in de tweede plaats kan je nu al in de problemen komen:
Hier krijg je nu al een foutmelding. In een setter had je dat al kunnen afvangen door ofwel te checken, ofwel te typecasten. Dus nu ga je eigenlijk al checks invoeren.




