Podpora načítání více konfiguračních souborů

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
VeN
Člen | 46
+
0
-

Ahoj,

vím, že se na fóru již několikrát řešil požadavek na možnost načítání více konfiguračních souborů. Zajímalo by mě, zda je reálné, aby pro to v blízké době byla podpora přímo v Nette. Aby byla zachována zpětná kompatibilita, tak bych si představoval, že by mohla vzniknout nová metoda, která by přidávala další konfiguraci k té, která se načetla zavoláním

Environment::loadConfig();

Nová metoda by třeba mohla být takováto:

Environment::appendConfig(APP_DIR . '/database.ini');

Jaký na tuto věc panuje názor?

VeN
Člen | 46
+
0
-

Z toho co David napsal

ad Environment a konfigurace: to nechme na další vlákno.

jsem pochopil, že na to chce založit jiné vlákno, tak jsem ho založil.

Z mého pohledu se mi zdá, že načtení více souborů se týká spíše Environmentu, než samostatné třídy \Nette\Config\Config, přes kterou to lze vyřešit poměrně dobrým workaroundem https://forum.nette.org/…nich-souboru#…

Jan Tvrdík
Nette guru | 2595
+
0
-

Use case

Na projektu pracuje 5 vývojářů. Kromě toho existuje testovací a produkční server. Celkem tedy 7 různých prostředí. Každé prostředí má jiné cesty, jiné přihlašovací údaje do DB a běží na jiné doméně, takže je potřeba i různý Google Maps API klíč.

Jako nejvhodnější se ukázalo vytvořit kromě hlavního config.neon ještě config.local.neon, který bude zahrnut v .gitignore.

Realizace v současnosti a její problémy

$configurator = new Nette\Configurator;
$configurator->loadConfig('%appDir%/config.neon');
$configurator->loadConfig('%appDir%/config.local.neon');

Problémy

  • Nelze přepsat již nastartovanou službu (autorunem).
  • Generují se a následně načítají zbytečně 2 soubory. Přepsané parametry a služby se navíc vyskytují 2×.

Návrh řešení

Upravit metodu loadConfig tak, aby uměla zpracovat více souborů. (Přejmenovat na loadConfigs?). Je potřeba mergnout tu konfiguraci před tím, než bude aplikovaná. Funkce array_merge_recursive se ukázala být nepoužitelnou, protože nepřepisuje, ale připisuje.

Nakonec jsem to spojení vyřešil pomocí metody Nette\Utils\Arrays::mergeTree:

$config = array();
$files = array_reverse($files); // Arrays::mergeTree nepřepisuje, takže je třeba první vzít `config.local.neon`
foreach ($files as $file) {
	$tmp = Nette\Config\Config::fromFile($file, $section);
	$config = Nette\Utils\Arrays::mergeTree($config, $tmp);
}

Související vlákna

Lopo
Člen | 277
+
0
-

ja som si do mojho Cofigurator-a urobil taketo nieco:

	/**
	 * Merges 2nd config into 1st
	 *
	 * @param ArrayHash $c1
	 * @param ArrayHash $c2
	 * @return Config
	 */
	public static function mergeConfigs($c1, $c2)
	{
		foreach ($c2 as $k => $v) {
			if (array_key_exists($k, $c1) && $v!==NULL && (!is_scalar($v) || is_array($v))) {
				$c1[$k]=self::mergeConfigs($c1->$k, $c2->$k);
				}
			else {
				$c1[$k]=$v;
				}
			}
		return $c1;
	}

v bootstrapee mam potom

Environment::loadConfig(APP_DIR.'/bailiff.neon', $section, \Nette\Environment::loadConfig(APP_DIR.'/nette.neon', $section));
Environment::loadConfig(NULL, $section, TRUE);

a moj loadConfig():

	/**
	 * Loads global configuration from file and processes it
	 *
	 * @param string|Config file name or Config object
	 * @param bool|Config append new config to existing|given ?
	 * @return ArrayObject
	 */
	public static function loadConfig($file=NULL, $section=NULL, $append=NULL)
	{
		if (!$append) {
			return self::$config=\Nette\Environment::loadConfig($file!==NULL? $file : '%appDir%/config.neon', $section);
			}
		return self::$config=Configurator::mergeConfigs($append===TRUE? self::$config : $append, \Nette\Environment::loadConfig($file!==NULL? $file : '%appDir%/config.neon', $section));
	}

Editoval Lopo (2. 6. 2011 12:19)

Jan Tvrdík
Nette guru | 2595
+
0
-

Čímž imho neřešíš ani jeden ze dvou výše zmíněných problémů.

Lopo
Člen | 277
+
0
-

Jan Tvrdík napsal(a):

Čímž imho neřešíš ani jeden ze dvou výše zmíněných problémů.

to ze sa kazdy config vygeneruje do samostatneho php podla mna neni nejak problem … ale mozno by to chcelo nejakym sposobom ovplyvnit ci sa tak ma diat alebo vyplut nakonec vysledok …

prepisanie sluzieb – to som zatial netestoval

ono predsa len ten moj postup je uz starsieho datumu, mam dojem ze odkedy je neon

mkoubik
Člen | 728
+
0
-

Jan Tvrdík napsal(a):

BTW jak řešíte ty routy? routes.local.php? Teď jsem na ten problém taky narazil.

Jan Tvrdík
Nette guru | 2595
+
0
-

mkoubik wrote: Jak řešíte ty routy? routes.local.php? Teď jsem na ten problém taky narazil.

Na jaký? Já na něj asi ještě nenarazil :) Ale pokud existuje, tak routes.local.php bude použitelné řešení.

mkoubik
Člen | 728
+
0
-

Myslel jsem rozdílný routy v různých prostředích. Já mám v gitu extra větev pro každou instalaci, což mi nepřijde moc pohodlný. U routes.local.php mi přijde blbý že to neni verzovaný. Asi zkusim routes.<název prostředí>.php.

Ondřej Mirtes
Člen | 1536
+
0
-

Routy by na prostředí měly být nezávislé. Pokud do nich potřebuji zahrnout i doménu (tedy absolutní cesta se vzorem začínajícím na //), tak to řeším řádkem v configu.

mkoubik
Člen | 728
+
0
-

O doménu nejde, prostě je potřeba mít v různých prostředích různé tvary adres, ale uznávám, že to moc častý požadavek není. Dál bych tím tohle téma nespamoval.

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Nebylo by lepší, kdyby současná metoda loadConfig uměla přijímat jako první argument i pole souborů? To config je stejně takové neurčité slovo a loadConfigs mi zrovna neevokuje „načtení z více konfiguračních souborů“.

pekelnik
Člen | 462
+
0
-

Podpora pro více konfiguračních souborů: https://forum.nette.org/…tani-konfigu#…