Databáze a nastavení v config.neon
- aGr
- Člen | 45
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
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
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…
- Vojtěch Dobeš
- Gold Partner | 1316
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
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
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)
- esorimmer
- Člen | 23
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
esorimmer napsal(a):
Hledal jsem alternativu pro Environment:getUser() a tu jsem prozatím nenašel
User je v $configurator->container->user
;)
- uestla
- Backer | 799
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)