otazky zacatecnika, obecne MVC, prace s db,
- LovecAnimuk
- Člen | 9
Zdravim lidicky, poslednich par dnu jsem operoval s myslenkou udelat novy
projekt pod objektovym php, nakonec tedy s vyuzitim frameworku, konkretni volba
pak byl nette :)
Ze zacatku to sice vypadalo, ze tuto oblast kompletne opustim, kdyz jsem se
stval s uvodnim tutorialem (nemyslim, ze za vsechny chyby jsem mohl nutne ja,
ale to je v tuto chvili jedno :) )
Kazdopadne konkretne k dotazum, profesi jsem databazista, ale s vecma jako oop
apod. se do styku dostavam, avsak to oop mysleni mi jeste uplne nejde :)
Potreboval bych na strance zobrazit nahodne 2 ruzne uzivatele z tabulky
uzivatelu.
Tudiz ocekavam, ze by to mohlo vypadat nasledovne
Sablona: zobrazeni nicku uzivatele pomoci promenne
Prezenter: zavolani metody z modelu, kde bude podminka, ktereho uzivatele
nevracet (pouzitelnost pro oba uzivatele)
model: samotny select do databaze (reseno formou dvou modelu, manager a trida
typu radku tabulky)
jak to ale napsat? :) zatim mam neco takoveho:
sablona:
{block content}
<table>
<tr><th>fighterA</th><th>fighterB</th></tr>
<tr>
<td n:foreach="$fighterA as $avatar">{$avatar->name}</td>
<td n:foreach="$fighterB as $avatar">{$avatar->name}</td>
</tr>
</table>
Presenter:
<?php
final class FightPresenter extends BasePresenter
{
private $fightManager = NULL;
public function actionShowFighters()
{
$this->template->fighterA = $this->model->findAvatar($where = array(
'id' => 1,
)); //nyni fixne, v modelu resit random
$this->template->fighterB = $this->model->findAvatar($where = array(
'id' => 2,
));
}
/*
public function renderShowFighters()
{
//$this->template->message = 'We hope you enjoy this framework!';
}
*/
public function getModel()
{
if(!isset($this->fightManager))
$this->fightManager = new FightManager;
return $this->fightManager;
}
}
?>
Modely:
<?php
class FightManager
{
public function findAvatar($where = NULL)
{
return dibi::query(
'SELECT * FROM [avatars]',
'%if', isset($where), 'WHERE %and', isset($where) ? $where : array(), '%end'
)->setRowClass('Avatar');
}
}
?>
<?php
class Avatar extends DibiRow
{
public function __construct($arr = array())
{
parent::__construct($arr);
}
}
?>
Je to aspon naznak spravnym smerem? Jak predat parametr funkci findAvatar jake id ma prvni volany uzivatel a ktereho uz tudiz nevybirat?
Dekuji za pomoc, snad se to da po m pochopit ;)
- regiss
- Člen | 61
Ahoj nevim jestli jsem te uplne pochopil, toz navrhnu jak bych to udelal ja.
Osvedcilo se mi pouzivat BaseModel(kde nastavim spojeni) a pak ostatni modely dedi od nej.
<?php
//file BaseModel.php
use Nette\Object;
abstract class BaseModel extends Object {
private static $connection;
public function getConnection() {
if (self::$connection == NULL) {
self::$connection = new DibiConnection(\Nette\Environment::getConfig()->database);
}
return self::$connection;
}
}
?>
<?php
//file DB_Avatar.php
use Nette\Object;
class DB_Avatar extends BaseModel
{
public function getRandomUser()
{
return $this->connection->select('*')
->from('Users')
->where('some condition')
->orderBy("rand()")
->limit(2);
}
}
?>
Pak to vytahnes v presenteru
$query = new DB_Avatar();
$this->template->avatars = $query->getRandomUser()->fetchAll();
A predas do sablony
{foreach $avatars as $avatar}
{$avatar}
{/foreach}
Doufam, ze jsem tam nenasekal moc chyb :)
- LovecAnimuk
- Člen | 9
diky za nastin moznosti, vyuziti BeseModelu jako predka jsem tu taky
zkousel.
V tomto reseni dat kontrolu, aby nebyl vybran stejny uzivatel na prezenter nebo
do modelu?
A jak pripadne vybrat hodnotu drive vybraneho uzivatele?
diky za pomoc
edit: ted jsem se podival poradne a vidim, ze rovnou tahas 2 uzivatele z db, to je taky moznost, ale asi by bylo vhodnejsi z logiky aplikace je tahat zvlast
Editoval LovecAnimuk (16. 12. 2010 9:05)
- LovecAnimuk
- Člen | 9
Jeste bych tedy upresnil co aktualne bych potreboval zodpovedet, pokud by mel
nekdo cas :)
1] v ramci MVC/MVP kam davat vypocty apod. do presenteru nebo do modelu?
(vypocty jsou myslene operace nad daty z db apod.)
2] nejake tutorialy(literatura) o praci v nette, kde by nebyly funkce jen pro
volani dat z db, ale i nejaka logika? (trochu navazuje na minulou otazku,
v ramci nette jde o ciste objektove phpko nebo je jeste nejak upravene?)
Vychazi to z toho uvodniho prikladu o zobrazeni dvouch ruznych nahodnych
uzivatelu z tabulky.
Kdyby slo o normalni phpko neni co resit, zavolam funkci na vyhledani prvniho
uzivatele v db(vyberu jich treba vice a randomem vyberu jednoho z nich),
ulozim si id do promenne, zobrazim ho, vyhledam druheho uzivatele s vyloucenim
id prvniho a zobrazim.
V nette a obecne MVC nevim kam tuhle logiku dat a jak ji napsat :)
diky za pripadny help a nasmerovani.
- Šaman
- Člen | 2666
Obecně, jestli nemáš zkušenosti s MVC-MVP ani s Nette, tak bych doporučoval začít bez modelu (první aplikace, seznámíš se s frameworkem).
Budeš mít jen presenter (zařizuje kompletní aplikační logiku) a pohledy (šablony a zobrazovací logika). Pak je jasné, že SQL půjde do presenteru.
A až se trochu rozkoukáš, tak začneš řešit problémy jako: potřebuji načítat uživatele podle ID, podle loginu, potřebuji všechny uživatele z jedné firmy, potřebuji dva náhodné uživatele – nebylo by dobré vytvořit si třídu Users a načítat vše na jednom místě? A začne ti vznikat model.
A pak můžeš jít ještě dál – načítací metody vrátí buď objekt MyUser (bo User je už zabraný Nette) nebo kolekci objektů. Kolekce (class Users) je třída potomků ArrayObject a umí řadit a filtrovat. (Takže řazení výsledků z různých dotazů se provádí jednotně.) Potom ještě zjistíš že je velmi praktické mít servisní vrstvu modelu a budeš s modelem tam co já teď.
Nebo ti ani to nebude stačit a třeba přijdeš na chuť pětivrstvému modelu
Proč jsem se tak rozepsal? Protože není jednoznačný návod jak na model. Vše, od prasení SQL do presenteru až po komplexní model o mnoha vrstvách je možné a za určitých podmínek i vhodné. Takže radši začni od nejjednoduššího (a taky od nejpodobnějšího s procedurálním programováním) a až zjistíš proč mít složitější model, tak na něj přejdi.
- LovecAnimuk
- Člen | 9
Diky za info, mas pravdu, ze takhle to bude idealni, proste do modelu
vytesnovat postupne veci tykajici se db apod.
Akorat jeste otazecka, nejaky pripadny link na literaturu, ukazkove priklady
apod. tutorialy zde na nette mam projite.
Nebo se pak jedna v podstate o ciste objektove php? a hledat tedy literaturu
tykajici se toho? s tim, ze nette pak pomuze s tou rozsirnou architekturou na
MVP
diky
- Šaman
- Člen | 2666
Nette ti pomůže s řízením celé aplikace a pokud budeš vycházet ze Skeletonu (teď je to tuším Sandbox) a tutoriálů, tak tě navede na správné oddělení aplikační a zobrazovací logiky.
Na databázi prý dneska vyšel commit který přidává přímo do Nette (zatím experimentálně) práci s db. Nicméně doteď bylo k dispozici Dibi, což je Davidova databázová vrstva která si s Nette super rozumí.
Já osobně používám obecnou SQL syntax a Dibi používám jen na
rychlejší a objektové volání dotazu. Samozřejmě se hodí pár dalších
fičurek které dotaz zpřehlední a celý zápis zjednoduší. Akorát si
nastuduj možnosti jak upravit výsledek dotazu (metody fetch, fetchAll,
fetchSingle a fetchAssoc) to je hodně killer fičurka.
Možností dibi je ale více, např. objektové skládání dotazu viz.
dokumentace.
Další možností je použít notORM. Vypadá to, že Nette\Database bude vycházet z obou výše uvedených knihoven.
Možností je spousta (v doplňcích jsou tuším dva ORMy pro Nette, někdo doporučuje Doctrine) ale Dibi a notORM budou zřejmě Nette provázet dále.
S objektovostí či neobjektovostí si hlavu nelámej. Všechno v Nette se snaží být objektové ale pokud nezačneš používat nějaký ORM tak se změní jen zápis jak zavolat SQL dotaz. Rozhodně na to abys používal Dibi nepotřebuješ vědět o OOP skoro nic.
Editoval Šaman (16. 12. 2010 13:50)
- LovecAnimuk
- Člen | 9
Opet diky za info. Osobne s dibi problem nemam, kdyz vezmu v potaz, ze kdyz jsem naposled delal vetsi projekt, tak jsem si vsechny funkce pripravoval sam, tak tohle je velka uleva :)
Spise se musim prehodit z proceduralnio mysleni na oop, at uz na urovni prezenteru nebo modelu :)