arrayParser (?)
eerst en vooral sorry voor de slecht titel maar ik heb nog geen idee hoe ik het beestje wil noemen.
Situatie zit zo: ik heb een config.yml file die ik inlees met de Symfony Yaml parser. Van die parser krijg ik een array terug. Nu wil ik die array "herschrijven" (lees de vorm veranderen). Ik heb hier een kleine classe voor geschreven maar ik vroeg me af, is dit wel deftig, kan het niet beter?
config.yml
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
db:
class: \PDO
host: localhost
user: root
password: test123
db: databank1
DBstorage:
class: \Jframe\Storage\PDOStorage
db: test
class: \PDO
host: localhost
user: root
password: test123
db: databank1
DBstorage:
class: \Jframe\Storage\PDOStorage
db: test
Ik heb mijn .yml bestand in deze structuur geschreven omdat dat lekker duidelijk is.
parser
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
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
<?php
require '../vendor/autoload.php';
use Symfony\Component\Yaml\Parser;
class configParser
{
public $parameterBag = array();
public function parseArray($values)
{
foreach($values as $key => $value)
{
foreach($value as $blahkey => $blah)
{
$this->setParam($key.'.'.$blahkey,$blah);
}
}
}
public function setParam($key, $value)
{
$this->parameterBag[$key] = $value;
}
public function getParam($key)
{
if(array_key_exists($key, $this->parameterBag))
{
return $this->parameterBag[$key];
}
else
{
throw new exception('Key not found');
}
}
// enkel voor testen
public function dump()
{
var_dump($this->parameterBag);
}
}
$yaml = new Parser();
$parser = new configParser();
$values = $yaml->parse(file_get_contents('../app/config/config.yml'));
$parser->parseArray($values);
// $parser->dump();
echo $parser->getParam('db.class'); // \PDO
echo $parser->getParam('db.user'); // \root
echo $parser->getParam('DBstorage.class'); // \Jframe\Storage\PDOStorage
?>
require '../vendor/autoload.php';
use Symfony\Component\Yaml\Parser;
class configParser
{
public $parameterBag = array();
public function parseArray($values)
{
foreach($values as $key => $value)
{
foreach($value as $blahkey => $blah)
{
$this->setParam($key.'.'.$blahkey,$blah);
}
}
}
public function setParam($key, $value)
{
$this->parameterBag[$key] = $value;
}
public function getParam($key)
{
if(array_key_exists($key, $this->parameterBag))
{
return $this->parameterBag[$key];
}
else
{
throw new exception('Key not found');
}
}
// enkel voor testen
public function dump()
{
var_dump($this->parameterBag);
}
}
$yaml = new Parser();
$parser = new configParser();
$values = $yaml->parse(file_get_contents('../app/config/config.yml'));
$parser->parseArray($values);
// $parser->dump();
echo $parser->getParam('db.class'); // \PDO
echo $parser->getParam('db.user'); // \root
echo $parser->getParam('DBstorage.class'); // \Jframe\Storage\PDOStorage
?>
Nadeel: deze klasse kan maar 2 niveaus aan, indien ik in config.yml nog één niveau dieper ga zit ik terug met een array als value.
Gewijzigd op 08/02/2013 16:44:00 door Jasper DS
Op zich netjes gedaan maar je zou ook eigenlijk arrays kunnen mergen als je de values overschrijd bijvoorbeeld, hiermee bedoel ik dat je een method maakt die een config maakt en als ie bestaat dan overschrijd hij hem en anders voegt hij hem toe.
@Kevin, ik denk niet dat ik de arrays wil mergen. Alle keys moeten samen en hebben één value (string, int boolean maar geen array).
Stel nu dat ik dan ergens mijn dbuser nodig heb doe ik $config->get('db.user')
Gewijzigd op 08/02/2013 17:10:02 door Jasper DS
Code (php)
Eerste aanroep is dan zonder currKey, want die is op dat moment nog leeg.
Het lijkt me handiger om de manier van ophalen te veranderen, dan de manier van invoegen.
@Wouter, jij bedoelt dat ik mijn .yml file anders moet opstellen toch? Ik vind dit wel een erg duidelijke en makkelijke oplossing qua configuratie? Ik heb bij Symfony liggen zoeken maar daar worden er meer als 6 klassen gebruikt waardoor ik de lijn kwijt was... :p
@Jasper, nee ik bedoel dat je Parser::getParam() moet aanpassen zodat hij de punten omzet in het uitlezen van een array.
Oke Wouter ik ben mee. Ik geloof dat je bedoelt dat $parameterBag gewoon de array bevat die de yaml parser binnensteekt. Indien ik dan $parser->get('db.class') aanroep moet mijn script het volgende doen: $this->parameterBag['db']['class']?
https://gist.github.com/WouterJ/4740229
Deze maakt gebruik van de Symfony2.3 PropertyAccess component. Hierdoor heb je een enorm flexibele ParameterAccessor klasse, die zowel arrays als objects makkelijk kan uitlezen doormiddel van de '.'. Wat hij allemaal kan zie je in de unit test. Mocht je meer willen weten over de PropertyAccess component, de documentatie is al klaar maar nog niet online: https://github.com/WouterJ/symfony-docs/blob/8480e77fd15a9d93141e49fb155808bb7ff0c98d/components/property_access.rst
Ja, hoe ik het zou doen: Deze maakt gebruik van de Symfony2.3 PropertyAccess component. Hierdoor heb je een enorm flexibele ParameterAccessor klasse, die zowel arrays als objects makkelijk kan uitlezen doormiddel van de '.'. Wat hij allemaal kan zie je in de unit test. Mocht je meer willen weten over de PropertyAccess component, de documentatie is al klaar maar nog niet online: https://github.com/WouterJ/symfony-docs/blob/8480e77fd15a9d93141e49fb155808bb7ff0c98d/components/property_access.rst
config.yml
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
db:
class: \PDO
host: localhost
user: root
password:
hallo: jasper
daag: desmet
db: databank1
DBstorage:
class: \Jframe\Storage\PDOStorage
db: test
class: \PDO
host: localhost
user: root
password:
hallo: jasper
daag: desmet
db: databank1
DBstorage:
class: \Jframe\Storage\PDOStorage
db: test
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
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
<?php
require '../vendor/autoload.php';
use Symfony\Component\Yaml\Parser;
// use Jframe\Controller\FrontController;
$fc = new Jframe\Controller\FrontController();
class configParser
{
public $parameterBag = array();
public function setParamBag(array $params)
{
$this->parameterBag = $params;
}
public function getParam($key)
{
$keys = explode(".", $key);
//$key = implode('][', $keys);
$array = $this->parameterBag;
foreach($keys as $key)
{
$array = $array[$key];
}
return $array;
}
// enkel voor testen
public function dump()
{
var_dump($this->parameterBag);
}
}
$yaml = new Parser();
$parser = new configParser();
$values = $yaml->parse(file_get_contents('../app/config/config.yml'));
$parser->setParamBag($values);
// $parser->parseArray($values);
//$parser->dump();
echo $parser->getParam('db.class') . '<br/>'; // \PDO
echo $parser->getParam('db.user') . '<br/>'; // \root
echo $parser->getParam('DBstorage.class') . '<br/>'; // \Jframe\Storage\PDOStorage
echo $parser->getParam('db.password.hallo') . '<br/>'; // jasper
?>
require '../vendor/autoload.php';
use Symfony\Component\Yaml\Parser;
// use Jframe\Controller\FrontController;
$fc = new Jframe\Controller\FrontController();
class configParser
{
public $parameterBag = array();
public function setParamBag(array $params)
{
$this->parameterBag = $params;
}
public function getParam($key)
{
$keys = explode(".", $key);
//$key = implode('][', $keys);
$array = $this->parameterBag;
foreach($keys as $key)
{
$array = $array[$key];
}
return $array;
}
// enkel voor testen
public function dump()
{
var_dump($this->parameterBag);
}
}
$yaml = new Parser();
$parser = new configParser();
$values = $yaml->parse(file_get_contents('../app/config/config.yml'));
$parser->setParamBag($values);
// $parser->parseArray($values);
//$parser->dump();
echo $parser->getParam('db.class') . '<br/>'; // \PDO
echo $parser->getParam('db.user') . '<br/>'; // \root
echo $parser->getParam('DBstorage.class') . '<br/>'; // \Jframe\Storage\PDOStorage
echo $parser->getParam('db.password.hallo') . '<br/>'; // jasper
?>
Zorg wel even dat je je aan de standaarden houdt (het liefst PSR standaarden) en dus je klassenamen met een hoofdletter laat beginnen.
Standaarden komen in orde, dit is nog maar een test.php bestand :-)
Gewijzigd op 08/02/2013 18:06:18 door Jasper DS
Quote:
Standaarden komen in orde, dit is nog maar een test.php bestand :-)
Leer het jezelf gewoon aan om altijd via standaarden te scripten.
Quote:
Leer het jezelf gewoon aan om altijd via standaarden te scripten.
Oke, duidelijk! Ik zal er op letten. ;-)
Ik twijfel wel nog over de naam van deze klasse. Zoals ik al zei dient het als bridge tussen de DI-container en de .yml of wat ik ook zou kunnen doen is mijn .yml altijd op die manier uitlezen? Ik weet het niet goed...
Gewijzigd op 08/02/2013 18:14:33 door Jasper DS