Citat:
program mora da stane
Jesi mislio na ovo
Code:
return TRUE;
return FALSE;
ili da gore definisem argument
var $error = '';
Ako gresim molim te ispravi me.
Ne, bas sam mislio na:
Gledaj da bacas exception. To ti je komanda throw new exception('Tvoj tekst') ; Vremenom ces videti zasto da te ne pretrpam informacijama sad. True/false su odgovori na pitanje. Razmisljaj ovako: ja te pitam da li mozes da preneses kamion na ledjima. Ti kazes da ne mozes (TRUE/FALSE). No, ja ti ipak natovarim taj kamion, a ti bacis kasiku (exception)
Citat:
alfa-pro: Pa ovako ja evo iskreno ovo sam radio bzv cisto pokusavao nesto da izvedem i shvatim. Problem je sto ja teoriju znam, znam tacno sta je sta, ali ja jos uvek ne mogu da ukapiram sustinu OOP. Nerazumem namenu classe? To sto sada radim klasama to sam radio i obicnim funkcijama. Znam da se klase koriste pri vecim priojektima a sa funkcijama kod je glomazniji i tesko se snadjes, kada mi treba neka ispravka i dorada. Ne razumem npr evo ja imam funkciju koju koristim stalno za npr
DB u njoj imam sve od konekcije do izvrsenja upita itd... I sada napravim klasu ona ce da bude iste velicine kao i funkcija. Mislim kako se onda smatra da kod nije toliko glomazan.? Ok dobro da ne idem u OFF.
Nisi
nimalo otisao u OFF. Za razliku od nekih tvojih ranijih pitanja, ovo je zaista veoma dobro. To sam i ja mislio dok sam radio proceduralno; wtf bi stavljao takve funkcije u klasu, sigurno klase nisu izmisljene zbog autoload-a? Ja sam bio forsiran da ucim OOP (sto je dobro), ali skroz losiji pristup od ovoga sto sad radim. Recimo ovo: posle 4 meseca, nisam imao
predstave kako da uradim refactoring tog koda. A ja sam ga pisao, pa ti vidi. Umesto da radimo bez parametara (kao sto sad radim), mi smo slali po 2-3 parametra metodama, neki opcioni itd... Totalno pogresno, a na testove smo trosili od 5-8 puta vise vremena nego sto je potrebno. Uradis refactoring; sve ispocetka.
Dokle god postavljas pitanja, na dobrom si putu. Nikako nemoj da se slepo drzis necega sto si procitao na netu; nemoj ni meni ni nekom sa 3 diplome da verujes cisto na rec. UVEK razmisljaj o ponudjenoj ideji, uvek!
Citat:
Mitke pazi ja sam eto zamislio ovu db klasu tako sto bi je koristio za uspostavljanje veze sa bazom, normalno prosirio bi je gde bi dodao da se izvrsavaju upiti (INSERT, SELECT, UPDATE, DELITE itd..) Ovo je cisto samo test da vidim da li to uopste valja. Radim one unit testove jedan kod pisem po 1000x dok ne dobijem ono pravo.
BRAVO! Tako se uci programiranje. Daj da vidim kako izgleda neki test.
Citat:
Ali opet mi je sve to nekako nejasno. Evo dajem primer ja klasu za bazu bi nekako zbudzao i to bi radilo to razumem ali da me neko pita uradi klasu za logovanje i registraciju ili uradi kontroler klasu za MVC parent ne bi znao da beknem. Neznam sa php-om sam dosta presao i za kratko vreme sam radio lepe aplikacije, uradio sam i svoj CMS. Svaki dan radim googlam odem na php manuel ne razumem dosta toga jer je sve na ENG. dok su u skoli svi ucili ENG ja sam ucio FRANCUSKI tako da tek ucim engleski ali dobro koliko toliko razumem to je najveci problem. Od srpske dokumentacije sam jedva nesto nasao i to je nesto bzv. Veliki problem je u meni sto sam ja uvek ne zadovoljan sa sobom. Sve sto uradim licno ja to mi se ne svidja i obrisem posle sat vremena...
Da, ranije sam procitao da ne znas engleski. I slazem se; u velikim si problemima zbog toga, zato cu ti pomoci. Dobro si krenuo, moj mentor mi lepo rekao: 'program je ziv, on se stalno menja'. Koliko god moji klijenti bili zadovoljni mojim radom i programom (a imam zahtevne klijente), ja nisam zadovoljan i uvek hocu bolje.
Ajde ovako da probamo:
koliko ti je problem da naucis sta je Active-Record? Za pocetnika je prilicno lako u odnosu na UnitOfWork. Evo ti hint kroz primer Doctrine 1.2 ORM programa, nisam dobar u teoretisanju:
Recimo da imas tabele Category i Product. One su one-2-many povezane, tj. kategorija ima mnogo proizvoda. U bazi, to znaci da tabela 'product' ima kolonu 'category_id', verujem da si upoznat sa ovim.
U tvom programu hoces da izlistas sve kategorije. Kod za to je:
Code:
$allCategories = CategoryTable::getInstance()->findAll() ;
Vidis; nema SQL-a, ORM se sam brine oko toga. $allCategories ce biti niz sa recimo 5 instanci klase Category; atributi te klase ce biti identicni kolonama iz tabele. Npr. kolona 'name', 'created_at', 'slug' ... itd...
Naravno, Active Record nije napravljen zbog toga, za tako nesto je dovoljan i mysqli. Ali ajde da predjemo na pravu zabavu:
kod ORM-a tipa Doctrine, tvoja klasa Category radi extend BaseCategory, a ona radi extend Doctrine_Record. Metoda delete() se nalazi u Doctrine_Record klasi; sto znaci da ti mozes da ukucas $category->delete(), iako nemas delete() u klasi Category. To ti je primer nasledjivanja, ODLICNA stvarcica, nauci je dobro.
Znaci, ako uradis brisanje kategorije, automatski se brisu i proizvodi. Medjutim, ti zelis da sprecis brisanje kategorija ako ona ima neke proizvode; prilicno logicno, ljudi grese, ovako ih sprecavas u tome. Znaci, prvo sto uradis je da napravis metodu Category::isDeletable() ;
Code:
class Category extends BaseCategory
{
public function isDeletable()
{
if ( count($this->getProducts()) == 0 )
return true ;
return false ;
// cistiji kod je linija ispod, nauci ternary operator
return count($this->getProducts())==0 ;
}
public function delete()
{
if ( !$this->isDeletable() )
throw new Exception('Category can not be deleted') ;
return parent::delete() ;
}
public function getProducts()
{
return $this->Products ;
// ili u tvom programu neki drugi tip ucitavanja, ovo je lazy load
}
}
Kako bi ovo iskoristio? Recimo, u administraciji tvog programa izlistas sve kategorije. Pored imena, hoces da postavis i ikonicu za brisanje; medjutim, neces dozvoliti da se kategorija obrise ako ima neke proizvode. Znaci:
Code:
foreach ($allCategories as $category) {
echo 'Ime:' . $category->getName() ;
if ( $category->isDeletable() ) {
// ikonica za brisanje
}
}
Objasnjenje:
isDeleteable() ce da vrati true/false u zavisnosti od toga da li je broj pripadajucih proizvoda veci od nule. Nju mozes i da iskoristis u view delu da prikazes ikonu/link za brisanje ili ne.
Medjutim, neko nastavi tvoj rad i u view delu ipak ispise link za brisanje, bez obzira da li moze to da uradi ili ne. Ako kategorija dobije delete() komandu, ona ce ipak jos jednom da proveri celu pricu, za svaki slucaj. Ako ne moze da se obrise, baca exception. Ako moze, tek tada ce se pozvati originalna delete() metoda koja ce uraditi brisanje iz baze.
Zasto je ovo jos bitno;
recimo, program ima vise administratora. Postoji kategorija 'Automobili', ali nijedan proizvod u njoj. 2 admin-a su ulogovana, obojica posmatraju listu svih kategorija i obojica znaci imaju link za brisanje. Medjutim, admin 1 doda neki proizvod npr. 'Jugo'. Admin 2 i dalje ima link za brisanje jer nije osvezio stranicu. On klikne na nju; da nema gornje provere, kategorija 'Automobili' i proizvod 'Jugo' bi bili obrisani, zar ne?
Na gornjem primeru mozes i da vidis zasto je
veoma bitno da ne saljes parametre; napisati unit test za ovo je 2 minuta posla. Ali ajde da prosirimo pricu jos malo; recimo da jednog dana uradis one-2-many izmedju Category i Image tj. ako kategorija ima neke slike, opet nece moci da se obrise. Cisto primer. Gornji kod bi se prepravio za 2 minuta:
Code:
public function getImages()
{
return $this->Image ;
}
public function isDeletable()
{
return ( count($this->getProducts()) == 0 AND count($this->getImages())==0 ) ;
}
a ti samo dodas jos jedan test za metodu isDeletable(). Konkretnije; u bootstrap ces imati jednu kategoriju totalno praznu, jednu kategoriju samo sa proizvodima, jednu sa slikama i jednu i sa slikama i sa proizvodima. Ako pretpostavimo da kategorija ciji je ID=4 ima i slike i proizvode, test bi bio nesto poput:
Code:
public function test_isDeleteable_CategoryWithProductsAndImages()
{
$category = CategoryTable::getinstance()->find(4) ;
$this->assertFalse($category->isDeletable()) ;
}
Javi da li si razumeo sve ovo. Ako jesi, ocekujem 'ladno pivo