Dědění db spojení z hlavni třídy

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

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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;
}