Variable van parrent class aanroepen
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?
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.
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?
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.
het is inderdaad ook de bedoeling code te re-usen. dus ik laat het zo
thx
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
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');
?>
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.
@erwin: waar bewaar jij je config-gegevens dan?
Bedankt voor de reacties. Frank.
Mijn Oauth config class is een algemene class die dus niet applicatie specifieke gegevens in zich heeft zitten.
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
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.
En dan vind je redenering dat je nooit public properties mag hebben niet logisch.
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
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.
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
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.