OOP static class met interface?
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
interface Logger {
/**
* @acces public.
*/
public static function construct();
/**
* @acces public.
* @param $message String.
*/
public static function config($message = null);
/**
* @acces public.
* @param $message String.
*/
public static function info($message = null);
/**
* @acces public.
* @param $message String.
*/
public static function fine($message = null);
/**
* @acces public.
* @param $message String.
*/
public static function warning($message = null);
/**
* @acces public.
* @param $message String.
*/
public static function error($message = null);
/**
* @acces public.
* @param $level String.
* @param $debug String.
* @param $message String.
*/
public static function log($level = null, $debug = null, $message = null);
}
?>
interface Logger {
/**
* @acces public.
*/
public static function construct();
/**
* @acces public.
* @param $message String.
*/
public static function config($message = null);
/**
* @acces public.
* @param $message String.
*/
public static function info($message = null);
/**
* @acces public.
* @param $message String.
*/
public static function fine($message = null);
/**
* @acces public.
* @param $message String.
*/
public static function warning($message = null);
/**
* @acces public.
* @param $message String.
*/
public static function error($message = null);
/**
* @acces public.
* @param $level String.
* @param $debug String.
* @param $message String.
*/
public static function log($level = null, $debug = null, $message = null);
}
?>
Nu maak ik gebruik van een log die alles opslaat in een bestand met de code:
Nu is mijn vraag: Wat als ik een log wil maken die mij alles e-mailt. Moet ik dan overal in mijn website LoggerFile veranderen naar LoggerEmail (LoggerEmail is natuurlijk weer een class). Maar is hier geen betere manier voor, zodat ik maar met een geringe aanpassing de log kan veranderen van LoggerFile naar LoggerEmail? Het gaat om een static class zodat ik overal en makkelijk de log kan aanroepen.
Kan toch in 1 functie?
Met __LINE__ en __FILE__ en __DIR__ etc kan je precies vinden welke regel het is.
Zelf heb ik bijvoorbeeld een log class die zichzelf registreert bij elke class in mijn applicatie als een observer. Elke class zelf kan vervolgens een interne functie aanroepen (die is aangemaakt in een abstracte basis class waar alle classes van afstammen) die vervolgens de log aanroept om de melding te doen. De log class vervolgens heeft weer een soort mapper erachter die de boel opslaat. Op die manier kan elke class een melding genereren en wordt het ofwel opgeslagen in een database (als die beschikbaar is), ofwel in een tekst bestand.
http://www.phphulp.nl/php/forum/topic/de-opbouw-van-een-logging-class/81508/#577390
En hertog, ja. Als je het nu wilt veranderen dan zul je overal alleen het initializen moeten aanpassen. Dat is natuurlijk niet zo handig. Vandaar dat je het Dependency Injection pattern moet gebruiken, of meer preciezer een Service Container:
Zo hoef je alleen in de bootstrap logger.class aan te passen. Meer hierover: http://www.phphulp.nl/php/tutorial/classes/dependency-injection/760/ en http://fabien.potencier.org/article/11/what-is-dependency-injection en http://fabien.potencier.org/article/12/do-you-need-a-dependency-injection-container
@Eddy, natuurlijk alles kan in flat PHP of met een functie. Maar niet zo flexibel als het nu is, en natuurlijk niet zo mooi.
Ik gebruik altijd het die dat Jelmer hier mooi heeft weergegeven: En hertog, ja. Als je het nu wilt veranderen dan zul je overal alleen het initializen moeten aanpassen. Dat is natuurlijk niet zo handig. Vandaar dat je het Dependency Injection pattern moet gebruiken, of meer preciezer een Service Container:
Code (php)
Zo hoef je alleen in de bootstrap logger.class aan te passen. Meer hierover: http://www.phphulp.nl/php/tutorial/classes/dependency-injection/760/ en http://fabien.potencier.org/article/11/what-is-dependency-injection en http://fabien.potencier.org/article/12/do-you-need-a-dependency-injection-container
@Eddy, natuurlijk alles kan in flat PHP of met een functie. Maar niet zo flexibel als het nu is, en natuurlijk niet zo mooi.
In die Service Container kan ik bv alles in zetten zoals database, config, logger etc zoals je in dit topic al aangaf http://www.phphulp.nl/php/forum/topic/oop-config-class/85756/
Elke service krijgt zijn eigen properties (in het geval hierboven logger.class) en elke service krijgt op zijn minst 1 functie (logger) om zichzelf aan te maken. Maar het voorbeeld hierboven is heel erg simpel. Mooiere voorbeelden van het gebruik van service containers: http://www.phphulp.nl/php/forum/topic/pad-ophalen-in-oop/84167/#599080 of http://www.phphulp.nl/php/forum/topic/ontwerpen-usermanagement/85413/#610232
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
$this->container->setContainer('config.class', 'Config_ConfigParserINI');
$this->container->setContainer('config.config.ini', dirname(__FILE__).'/../../config.ini');
$this->container->setContainer('config', function($container) {
$class = $container->getContainer('config.class');
$config = new $class();
return $config->parseConfigByFile($container->getContainer('config.config.ini'));
});
?>
$this->container->setContainer('config.class', 'Config_ConfigParserINI');
$this->container->setContainer('config.config.ini', dirname(__FILE__).'/../../config.ini');
$this->container->setContainer('config', function($container) {
$class = $container->getContainer('config.class');
$config = new $class();
return $config->parseConfigByFile($container->getContainer('config.config.ini'));
});
?>
1 ) Stel ik heb het volgende: Ik heb een userMapper en die heeft de config class en database class nodig. Wat is dan beter, de volledige $this->container of $this->container->getContainer('config') en $this->container->getContainer('database') mee te geven aan de constructor?
2 ) Als ik 5x $this->container->getContainer('config')->getConfig('database.name') doe, zoals ik dan begrijp uit mijn logica word er 5x een new Config() gedaan? Dat lijkt mij niet de bedoeling toch? Of is de bedoeling om dit te doen (bedoel je dat met 'en elke service krijgt op zijn minst 1 functie (logger) om zichzelf aan te maken.'):
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<?php
$this->container->setContainer('config.class', 'Config_ConfigParserINI');
$this->container->setContainer('config.config.ini', dirname(__FILE__).'/../../config.ini');
$this->container->setContainer('config.constructor', function($container) {
$class = $container->getContainer('config.class');
$config = new $class();
return $config->parseConfigByFile($container->getContainer('config.config.ini'));
});
$this->container->setContainer('config', $this->container->getContainer('config.constructor'));
?>
$this->container->setContainer('config.class', 'Config_ConfigParserINI');
$this->container->setContainer('config.config.ini', dirname(__FILE__).'/../../config.ini');
$this->container->setContainer('config.constructor', function($container) {
$class = $container->getContainer('config.class');
$config = new $class();
return $config->parseConfigByFile($container->getContainer('config.config.ini'));
});
$this->container->setContainer('config', $this->container->getContainer('config.constructor'));
?>
3 ) En is mijn logger aanpak goed wat betreft het gebruik van een interface?
Gewijzigd op 20/07/2012 21:46:31 door Joakim Broden
Maar om te antwoorden 2x de aparte meegeven is het beste. En misschien de mapper ook nog ContainerAware maken, zodat we getContainer in de Mapper kunnen aanroepen.
Lees anders ook die tutorial van Pim die ik je gaf, die legt dit allemaal uit.
2) Ja dat klopt en dat is natuurlijk niet jou bedoeling. Vandaar dat we iets moeten maken wat een shared service heet. Ook dit heeft Pim beschreven.
Ik zou ook i.p.v. je eigen container pimple gebruiken. Dit is een mooie container met alles er al in
3) je interface is goed, al zou ik al dat static weghalen
En even de code die je hier geeft is niet helemaal goed. Als config.constructor en config gelijk zijn, waarom dan niet die 2 samenvoegen en in 1 keer config maken?