Autor | Zpráva | ||
---|---|---|---|
Donny Profil * |
#1 · Zasláno: 8. 8. 2012, 12:23:14
Dobrý deň,
začal som si tak trochu študovať objektové programovanie v php, dá sa povedať že už pomerne skoro som narazil na problém.. skrátene, mám 3 základné subory na ktorých by som chcel stavať: - Súbor mainClass.php - obsahuje komplet prácu z databázou - Súbor aditionalClass.php - iné pre dôležité funkcie, ktoré by mali s databázou pracovať - Súbor test.php - testovací, spúšťací súbor Poznámka: Funckie v súboroch sú vo väčšine skrátené a fungujú a pre moju situáciu ktorú riešim sú nepodstatné.. mainClass.php class mod_db { function connection() { // pripojenie na db } function update() { //update } function insert() { //vlozenie } function delete() { //zmazanie } } aditionalClass.php Class pridavnaTrieda extends mod_db { function setLanguage($setupID, $userID, $langID) { /* - setupID = poradove cislo v tabulke userSetup - userID = id uzitela - langID = id jazyka */ $updateString = "userID = '$userID', langID = '$langID', lastChange = now()"; $sql->update("$tabulka1", "$updateString", "setupID = '$setupID'"); } } Subor test.php //nacitanie externych suborov include('settings.php'); include(libraries.'mainClass.php'); include(libraries.'aditionalClass.php'); //spustenie tried $sql = new mod_db(); $create = new pridavnaTrieda(); //spustenie toho co potrebujem $create->setLanguage($setupID, $userID, $langID); No a tu nastáva vec ktorej tak celkom nerozumiem. Funkcia setLanguage využíva update databáze (teda funkciu z triedy mod_db) a napriek tomu že táto trieda už je spustená v podobe ako to mám zapísané to nefunguje. Po drobnej úprave súboru aditionalClass.php to fungovať začne, ale .. takto to funguje Class pridavnaTrieda extends mod_db { function setLanguage($setupID, $userID, $langID) { include('settings.php'); include(libraries.'mainClass.php'); $updateString = "userID = '$userID', langID = '$langID', lastChange = now()"; $sql->update("$tabulka1", "$updateString", "setupID = '$setupID'"); } } Toto riešenie my príde ako blbosť a predstavuje to pre mňa 2 zbytočné riadky vždy pri práci s databázov.. Do takého riešenia sa my veľmi ísť nechce, nezdá sa my efektívne.. Premýšľal som nad využitím výrazu public ale tak to tiež nefugnovalo.. Vedel by ste ma niekto nasmerovať čo robím zle, resp. čo som nepochopil? Ďakujem. |
||
ShiraNai7 Profil |
Neextendoval bych mod_db - ale instanci mod_db predaval v konstruktoru, priklad:
class pridavnaTrieda { protected $db; public function __construct(mod_db $db) { $this->db = $db; } public function setLanguage($setupId, $userId, $langId) { $this->db->update( ... ); } } Ale cele tve reseni je nejake prapodivne. Konfiguracni veci bych dal alespon do konstant nebo nejlepe do instance tridy urcene pro tento ucel. Neni dobre psat kod pulka OOP, pulka procedural. |
||
Ugo Profil |
#3 · Zasláno: 8. 8. 2012, 13:18:15
ještě dodám důvod proč to nefunguje .... jde o viditelnost proměnných, $sql definuješ v globálním prostoru a ve funkci třídy tedy není přístupná a musíš jí tam nějak dostat, doporučuji to co ShiraNai7 . Pro pochopení si tam ale můžeš ještě dát global $sql; na začátek té fce.
|
||
Donny Profil * |
#4 · Zasláno: 8. 8. 2012, 13:55:35 · Upravil/a: Donny
Ďakujem páni, na základe rád som to (čiastočne) vyriešil. Momentálne skúšam vytvoriť spomínanú konfiguračnú triedu..
To že to nefunguje kvôli viditeľnosti som viac menej predpokladal, ale napriek tomu sa nemôžem ubrániť dojmu že veci definujem (resp. musím definovať) x krát. a to my príde nepraktické.. |
||
ShiraNai7 Profil |
#5 · Zasláno: 8. 8. 2012, 14:00:45
Donny:
Závislosti stačí "definovat" (předat přes konstruktor) pouze jednou.. a to při vytváření instance daného objektu. Pak je jen používáš. |
||
Ugo Profil |
#6 · Zasláno: 8. 8. 2012, 14:14:09
Donny:
nepraktické to v určitých situacích je, ale má to právě tu výhodu že když to "definuješ" víckrát, tak to můžeš víckrát zadefinovat trošku jinak, což ti může pomoct při úpravách a znovupoužití stejného kusu kódu |
||
Donny Profil * |
#7 · Zasláno: 8. 8. 2012, 14:15:40
ShiraNai7
Áno rozumiem že v aktuálnom prípade sa jedná o jedno predanie do prídavnej triedy, osobne sa ale zamýšľam aj trošku dopredu.. Programovaniu sa venujem viac menej amatérsky ale už som si na určitý systém práce zvykol, je pre mňa prehľadný. Preto prepokladám že budem mať viac tried s ktorými budem pracovať v rôznych situáciách. Len tak z hlavy ma napádajú tak 4 ďalšie základné triedy, ktoré by spravovali iné funkcionality. Základné načítanie sa dá vyriešiť funkciou autoload ale keďže všetky funkcie budú pracovať s databázou + budú potrebovať konfiguráciu, vzniká tu duplicita funkcie construct ktorá tam bude musieť byť vždy, tj. min 3 riadky vždy. Ak sa jedná o pár tried nie je to nič tragické ale ak by som tých tried mal 40 tak je to už trošku také ťažkopádnejšie.. aspoň mne to tak príde |
||
Ugo Profil |
<?php class DatabaseWorker { protected $db; public function __construct($db) { $this->db = $db; } } class pridavnaTrieda extends DatabaseWorker { /* uz bez constructu */ } je to taková rodina pracovníku s databázi kde se řemeslo předává z generace na generaci již při narození :D |
||
ShiraNai7 Profil |
#9 · Zasláno: 8. 8. 2012, 14:55:34
Hlavně dělej 1 třídu na 1 věc. Nedělej univerzální supertřídy třídy na všechno.
|
||
Donny Profil * |
#10 · Zasláno: 8. 8. 2012, 15:15:34
Ugo:
Zaujímavý námet, Ďakujem :). Napáda ma preto otázka prečo (ak to teda ide takto) nemôžem využiť priamo tú triedu mod_db, ktorá spravuje všetky veci ktoré slúžia na pripojenie? class mod_db { protected $db; public function __construct($db) { $this->db = $db; } // pripojenie na db public function connection() { } //update public function update() { } //vlozenie public function insert() { } //zmazanie public function delete() { } } ShiraNai7: áno, na toto som narážal, som zvyknutý oddelovať funkcionality.. 1. súbor - databáza 2. súbor - jazykove nastavenia 3. súbor - identifikácia 4. Súbor - štatistiky a podobne, keď som si to premietol na to že to "preklopím na triedy" tak to na mňa pôsobilo dosť neprakticky.. |
||
Majkl578 Profil |
#11 · Zasláno: 8. 8. 2012, 16:25:24
Donny:
„prečo nemôžem využiť priamo tú triedu mod_db, ktorá spravuje všetky veci ktoré slúžia na pripojenie“ Protože by to nedávalo smysl. Třída se nestará o připojení, ale o pouze manipulaci s daty. Nebude připojení ani sama nějak tajuplně vytvářet. Třída připojení jen využívá, tudíž jej dostane v konstruktoru (jako závislost) a následně bude pouze využívat. |
||
Lamicz Profil |
#12 · Zasláno: 8. 8. 2012, 18:36:32
Donny
Zastávám názor, že základní výhoda OOP je autoload tříd. Nastudování ušetří spoustu require a problémů s chybějícími třídami. |
||
Časová prodleva: 13 dní
|
|||
Donny Profil * |
#13 · Zasláno: 21. 8. 2012, 11:15:42
Dobrý deň,
Po vašej rade, som sa tejto tematike začal intenzívnejšie venovať a opäť som narazil na problém, keďže to viac menej pokračuje nebudem vytvárať nové vlákno, aby sa nestratilo prepojenie s týmto problémom. Vytvoril som si triedu front, ktorej úlohou je generovať načítanie a spustenie konkrétnej triedy a metódy na základe adresy, funguje to takto: www.nieco.sk -> spustí základnú preddefinovanú triedu www.nieco.sk/blog -> načíta subor class.blog.php, triedu blogControler a metodu blog() www.nieco.sk/blog/clanok/1/ -> načíta subor class.blog.php, triedu blogControler a metodu clanok() s id 1 Princíp je fajn, funguje to presne tak ako si predstavujem (nepodstatné časti kódu v ukážke preskakujem,nakoľko je to dlhé), mám tu však 1 problém + 1 otázku. <?php class Front { protected $_file; protected $_controller; protected $_method; public function run() { //spracovanie adresy $route = str_replace(ALIAS, '', $_SERVER['REQUEST_URI']); $params = explode('/', trim( $route, '/') ); if(!empty($params [1])) { /* overenie jednotlivych parametorv z adresy a nacitanie premených subor.php do premenej this->_file, trieda do $this->_controller metoda do $this->_method */ } else { //ak nie je param, nacitaj hlavnu triedu } } // ak subor existuje nacitaj ho a spusti prislusne veci if (file_exists($this->_file)) { require($this->file); $className = $this->_controller. 'Controller'; $controller = new $className(); call_user_func(array($controller, $this->_method)); } else { require("class.extensions"); $controller = new extensionsController; call_user_func(array($controller, "chyba()")); } } a tu je problém resp. otázka. 1. v jednotlivých triedach občas potrebujem pracovať s databázov, ak nadväzujem na našu predošlú diskusiu a vašu radu mal by som teda pri takomto automatizovanom postupe funkcie spúšťať takto $controller = new $className($sql); a do každej triedy tým predávať možnosť pripojenia na sql databázu? Ak som tomu teda porozumel správne, tak trieda blog by pre otestovanie mohla vyzerať takto: blog.php <?php Class blogController { protected $db; public function __construct($sql) { $this->db = $sql; } //vyber z tabulky public function blog() { $query = "SELECT * FROM `$tabulka1`"; $dotaz = mysql_escape_string($query); $pocet = $this->db->nums($query); echo $pocet; } } ?> Výsledok je ale pre mňa dosť prekvapivý, Call to a member function nums() on a non-object, čo znamená že nie je možné spúšťať metodu mimo objektu, ale veď nato tam dávam to dedenie nie? 2. je lepsie používať call_user_func() alebo klasické $controller->metoda(); |
||
ShiraNai7 Profil |
#14 · Zasláno: 21. 8. 2012, 13:03:56
Donny:
„Výsledok je ale pre mňa dosť prekvapivý, Call to a member function nums() on a non-object“ Určitě předáváš v konstruktoru tu instanci? Vydumpuj si před tím řádkem s chybou, co tam skutečně je. var_dump($this->db); „$dotaz = mysql_escape_string($query);“ Tohle je nesmysl ze 2 důvodů: 1) escapuješ celou query - proč? funkce se má používat na stringové části dotazu 2) když už máš funkce ohledně databáze v té třídě, tahle by tam měla být taky „2. je lepsie používať call_user_func() alebo klasické $controller->metoda();“ Vždy používej $objekt->metoda();. Funkce call_user_func/call_user_func_array() je pro případy, kdy to prostě jinak nejde (callback předaný v argumentu, popř. variabilní počet argumentů v poli, v PHP 5.4 můžeš proměnnou obsahující callback volat rovnou jako $promenna()). |
||
Donny Profil * |
#15 · Zasláno: 21. 8. 2012, 13:26:29
Pri pohľade na var_dump sa my "rozsvietilo", chyba bola že som predával $controller = new $className($sql); správne má byť $controller = new $className($this->_db);
Tohle je nesmysl ze 2 důvodů: 1) escapuješ celou query - proč? funkce se má používat na stringové části dotazu 2) když už máš funkce ohledně databáze v té třídě, tahle by tam měla být taky Berte len ako ukážkový kód, ale dám si na to escapovanie dotazu pozor a escapovaciu funkciu dám určite do triedy pre mysql. 2. Super. Ďakujem. |
||
Časová prodleva: 12 let
|
0