Dědění db spojení z hlavni třídy
- ondrakrajcik
- Člen | 45
Chtěl bych se zeptat na takovou blbůstku.
Ve složce Model mám třídy, které pracují s databází. Ve všech je proměnná $database přes kterou se posílají dotazy na databázi např. $database->table(‚uzivatel‘)->where(neco,neco);
Příjde mně nepohodlné v každé takové třídě mít proměnou a konstruktor
public function __construct(Nette\Database\Context $database){
$this->database = $database;
}
Navíc pokud chci vytvořit instanci takové třídy tak ve třídě kde instanci vytvářím musím mít opět takovýto konstruktor jako jsem uvedl a předat při vytváření instance $database. Což zbytečně komplikuje kód.
Proto jsem si říkal, že si založím třídu ze které se bude dědit. Do všech ostatních tříd.
Takto
class HlavniTrida{
protected $database;
// nechci tady mít konstruktor s parametrem Nette\Database\Context, chci konstruktor bez parametrů
public function __construct(){
$connection = new Connection('dsn', 'user', 'heslo');
$this->database = new \Nette\Database\Context($connection);
}
}
Takto mě to funguje, Jen mám problém s tím, že musím ručně zadávat dsn, user a password. Už je to přece v config.neon nastaveno. Dá se to nějak přetáhnout z configu sem?
A ještě jeden malý dotaz. Když pak rozšířím nějakou třídu touto třídou a zadám
$this->database->
tak mě v netbeans nevyskakuje nápověda metod a proměnných které můžu
použít. Jde to nějak opravit?
V této hlavní třídě kde vytvořím $database nápověda funguje, ale ve
zděděné již ne
- Etch
- Člen | 403
Hloupý dotaz…
Proč chceš mít konstruktor bez parametrů???
ondrakrajcik napsal(a):
Navíc pokud chci vytvořit instanci takové třídy tak ve třídě kde instanci vytvářím musím mít opět takovýto konstruktor jako jsem uvedl a předat při vytváření instance $database. Což zbytečně komplikuje kód.
Proč prostě modelové třídy nezaregistruješ jako služby a nenecháš předání závislostí na autowiring??
Editoval Etch (12. 3. 2014 12:32)
- David Matějka
- Moderator | 6445
Příjde mně nepohodlné v každé takové třídě mít proměnou a konstruktor
Tak to jsi nepochopil dependency injection. O tom to prave je – do konstruktoru (pripadne setteru nebo tak) si reknu, ze chci spojeni na databazi. Vic me to nezajima. Nekdo jinej mi to spojeni proste musi predat, jinak nemuzu pracovat.
Takto mě to funguje, Jen mám problém s tím, že musím ručně zadávat dsn, user a password. Už je to přece v config.neon nastaveno. Dá se to nějak přetáhnout z configu sem?
prave pomoci DI, ze si o tu sluzbu reknes v konstruktoru
- ondrakrajcik
- Člen | 45
matej21 napsal(a):
Příjde mně nepohodlné v každé takové třídě mít proměnou a konstruktor
Tak to jsi nepochopil dependency injection. O tom to prave je – do konstruktoru (pripadne setteru nebo tak) si reknu, ze chci spojeni na databazi. Vic me to nezajima. Nekdo jinej mi to spojeni proste musi predat, jinak nemuzu pracovat.
Takto mě to funguje, Jen mám problém s tím, že musím ručně zadávat dsn, user a password. Už je to přece v config.neon nastaveno. Dá se to nějak přetáhnout z configu sem?
prave pomoci DI, ze si o tu sluzbu reknes v konstruktoru
Můžete mně napsat nějaký jednoduchý příklad?
Dvě třídy: PrvniTrida, DruhaTrida. Druhá třída chci aby dědila od první třídy a nechci se ve Druhé třídě už obtěžovat předáváním parametrů. Ve Druhe tridě chci zdědit proměnnou $database z První třídy, přes kterou budu moct rovnou přistupovat k databázi.
Napíšu zde zdrojový kód Druhé třídy
class DruhaTrida extends PrvniTrida{
public function __construct(){
parent::__construct();// tady bych se nerad obtěžoval s předáváním database
}
// promenna $database je zdedena promenna z Prvni Tridy
public function getItems(){
return $this->database->table('uzivatel');
}
}
Jak bude vypadat První třída?
Editoval ondrakrajcik (12. 3. 2014 13:06)
- Etch
- Člen | 403
ondrakrajcik napsal(a):
Jak bude vypadat První třída?
class PrvniTrida{
protected $database;
public function __construct(\Nette\Database\Context $database){
$this->database = $database;
}
}
Ve chvíli, kdy si pak nainjectujes třídu „DruhaTrida“, tak se parametr $database předá automaticky. Nevytváříš pak instanci třídy „DruhaTrida“ „ručně“ pomocí operátoru „new“, ale budeš si jí vytahovat skrze DI Kontejner.
Konstructor v „DruhaTrida“ vynecháš úplně, pokud nepotřebuješ nějaké dodatečné parametry
Editoval Etch (12. 3. 2014 13:22)
- greeny
- Člen | 405
BaseRepository.php (rodičovská třída s konstruktorem)
<?php
namespace App\Model;
use Nette\Database\Context;
class BaseRepository { // or whatever
protected $database;
public function __construct(Context $database) {
$this->database = $database;
}
?>
SomeRepository.php (zděděná třída bez konstruktoru – ten zdědí)
<?php
namespace App\Model;
class SomeRepository extends BaseRepository {
public function doSomething() {
return $this->database->table('...')->where('...');
}
}
?>
config.neon:
services:
- App\Model\SomeRepository
# přidej všechny třídy co chceš používat
Použití:
<?php
namespace App\PublicModule;
class SomePresenter extends BasePresenter {
/**
* @var \App\Model\SomeRepository
* @inject
*/
public $someRepository;
public function renderDefault() {
$this->template->someVariable = $this->someRepository->doSomething();
}
}
?>
Edit: tak mě už někdo předběhl :D
Editoval greeny (12. 3. 2014 13:21)
- ondrakrajcik
- Člen | 45
Strašně děkuju, už je mně to jasné. A náhodou řešení problému číslo 2 někdo nezná? Já myslím, že tento nedostatek ani není možné odstanit, ale jen tak kdyby náhodou šel tak se ptám.
Dělám v programu NetBeans.
Konkrétně na příkladech co o příspěvek výše uvedl greeny, mně to funguje tak, že když v SomeRespository napíšu
$this->database->
tak mně nevyskočí nápověda od netbeansu.
Když udělámto samé v BaseRespository, tak nápovědu vyhodí, ale jakmile je to zděděná proměnná tak nápověda nefunguje.
- Jiří Nápravník
- Člen | 710
Mě to většinou netbeans pozná, ale můžeš tomu pomoci tak, že v té původní třídě pomocí phpdoc @var nastavíš typ té proměnné:
class BaseRepository { // or whatever
/**
* @var Nette\Database\Context
*/
protected $database;
public function __construct(Context $database) {
$this->database = $database;
}