Databáze a nastavení v config.neon

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

Mám problém s připojení se k databázi.
V bootstrapu mám klasiku ze sandboxu:

$configurator = new Nette\Configurator;
$configurator->container->params += $params;
$configurator->container->params['tempDir'] = __DIR__ . '/../temp';
$container = $configurator->loadConfig(__DIR__ . '/config.neon');

Když se ale snažím vytisknout

Debugger::dump( $container );

dostanu velké pole se spoustou údajů, ale přihlašovací údaje do DB nikde nevidím. Potřeboval bych vysvětlit jak config.neon pracuje.

A poté bych se hned připojil do DB, ale nevím přesně jak:

dibi::connect( $container->????['???'] );

Stejně tak v config.neon nemám nic jinak než bylo v sandboxu.

Fórum i návody jsem pečlivě procházel, často se to tu řeší, ale nic mě neuspokojilo. Navíc velmi často narážím na třídu Environment, která je však již depracated. Díky moc, mám v tom trochu hokej.

Editoval aGr (4. 7. 2011 10:53)

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

Parametry jsou v $container->params. Což je obyč pole. Nastavit vlastní params lze buď přímo:

$container->params['database'] = array('host' => 'xxx', ...);

nebo v NEON (resp. INI, ale proč, že?) konfiguráku:

common:
	database:
		host: xxx
		...
aGr
Člen | 45
+
0
-

Díky takhle to opravdu funguje, nicméně nerozumím, proč je to v tom sandboxu takto:

common:
	php: # PHP configuration
		date.timezone: Europe/Prague
		# session.save_path: "%tempDir%/sessions"
		# zlib.output_compression: yes

	services:
		robotLoader:
			run: true

		database:
			class: Nette\Database\Connection
			arguments: ['mysql:host=localhost;dbname=DB', 'USERNAME', 'PWD']

		model:
			class: Model
			arguments: [@database]

		authenticator:
			factory: [@model, createAuthenticatorService]

production < common:

development < common:

console < common:

Snažil jsem se dostat tedy k services/database/arguments. To tvoje je funkční, jen mě trochu mate k čemu tady ony arguments teda jsou…

22
Člen | 1478
+
0
-

tomu se říká Dependency Injection

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

Doplnil bych, že v poli arguments u služby database jsou přihlašovací údaje uvedené natvrdo, tzn. je to jak uvést je rovnou do konstruktoru. Pole services není nijak dostupné, ve volání loadConfig je zpracováno a zahozeno (vytváří se podle něj služby v $configurator->getContainer()). Takže co je uvedeno v arguments se do $container->params nikdy nedostane. Ale jde to naopak – co je v $container->params lze poslat do arguments.

use-case

Pokud bys chtěl třeba přihl. údaje jiné pro produkční režim a jiné pro development, tak bys to zapsal například takto:

common:
	services:
		database:
			class: Nette\Database\Connection
			arguments: ['%database.driver%:host=%database.host%;dbname=%database.dbname%', %database.username%, %database.password%]

	params:
		database:
			driver: mysql
			host: localhost
			dbname: DB
			username: USERNAME
			password: PWD

development < common:
	params:
		database:
			driver: mysql
			host: localhost
			dbname: DIFFERENT_DB
			username: DIFFERENT_USERNAME
			password: DIFFERENT_PWD
aGr
Člen | 45
+
0
-

22 napsal(a):

tomu se říká Dependency Injection

Dobrá, to se mi líbí a chtěl bych to používat. Tyto tři argumenty z configu se mi tedy dostanou do konstruktoru třídy Nette\Database\Connection ($dsn, $username = NULL, $password = NULL). Jak však nyní vytvořit nové připojení, když při volání

self::$defaultConnection = new Connection();

logicky dostávám „Missing argument 1“?

A ještě o jedno upřesněni bych vás poprosil: Nette používá pro DB třídy v Nette\Database (v tomto případě bych měl používat config s Injection), nároční si však ještě dostáhnou dibi (pro větší čáry s db) a používají config tak jak napsal vojtech.dobes v druhém příspevku. Je to tak?

vojtech.dobes napsal(a):

Díky, tomu myslím rozumím a určitě to použiju.

22
Člen | 1478
+
0
-

v aplikaci se ke kontaineru a připojení dostaneš přes:

$this->conn = $this->context->database;

ovšem lepši je si stvořit nějaký modelLoader a spojení strčit tam a v presenterech si volat jen modelLoader, který už je k DB připojený. Inspirace tutorial od Sirgiho..

Už ovšem neplatí to omezení pro config.neon a není třeba vytvářet tu továrnu na připojení, ale injektovat připojení rovnou do kontruktoru modelLoaderu.
nástřel:

common:
	services:
		modelLoader:
		arguments: [@dbConnection]

                dbConnetion:
                        class: Nette\Database\Connection
                        arguments: ['%database.driver%:host=%database.host%;dbname=%database.dbname%', %database.username%, %database.password%]

        params:
                database:
                        driver: mysql
                        host: localhost
                        dbname: DB
                        username: USERNAME
                        password: PWD

a pak v aplikaci:

$this->context->modelLoader('myModel')->someMethodFromModel();

Editoval 22 (6. 8. 2011 14:14)

aGr
Člen | 45
+
0
-

Tak snad rozumím, seč na ten tutorial to nejspíše předělám až budu v Nette jistější. Díky.

esorimmer
Člen | 23
+
0
-

Nevím jestli se nezeptám blbě, ale nejde to i přes Environment::loadConfig(); a Environment::getConfig(); ? Ptám se hlavně proto, pže jsou na ty příklady v tutoriálech. Díky za info.

aGr
Člen | 45
+
0
-

Pokud jsem dobře četl, tak Environment je již deprecated (zastaralé), takže bys ho srávně používat neměl. Taky mě to v těch návodech mátlo, jde o to, že ještě nejsou aktualizované. (Ale ber to s rezervou, jsem také začátečník :).)

esorimmer
Člen | 23
+
0
-

Jo to máš pravdu, taky jsem to někde četl, ale právě tam byl dovětek, že pro začátečníky se to ještě ponechá :-) Hledal jsem alternativu pro Environment:getUser() a tu jsem prozatím nenašel, takže jsem to ještě použil.
V návodech jsem třeba porovnával i rozdělení tříd do adresářů (libs\Nette), které již poslední verze má jiné a např. pro Application\AppForm jsem taky nemohl najít alternativu (asi UI\Form). Ale do toho se asi člověk po čase dostane. Jinak ty návody jsou super, bez nich by to určitě nešlo.
PS: není deprecated spíš zavržené :-)

Jan Voráček
Člen | 90
+
0
-

esorimmer napsal(a):

Hledal jsem alternativu pro Environment:getUser() a tu jsem prozatím nenašel

User je v $configurator->container->user ;)

uestla
Backer | 796
+
0
-

Alternativa ke Environment::getUser() je (stejně jako ostatní) zavolání služby (service) nad kontajnérem, čili

$configurator = new Nette\Configurator;
$container = $configurator->loadConfig(__DIR__ . '/config.neon');

$user = $container->user; // alternativa ke $container->getService('user')

Jde o to, že při vytvoření konfigurátoru se zaregistrují továrničky k základním službám (mj. i ke službě User), a tento kontajnér je probubláván do aplikace (tedy i k presenteru, ve kterém pak už stačí jen zavolat $this->getUser(), čímž se lze dostat k userovi v daném kontextu – tj. v tom, který byl v boostrapu vytvořen).

Editoval uestla (9. 7. 2011 22:42)