Autor | Zpráva | ||
---|---|---|---|
CistiC Profil * |
#1 · Zasláno: 18. 1. 2008, 13:19:59
Zdravím,
začínam s oop a hned jsem narazil na problém a nevím, jaké je správné řešení. ---------------------------------- index.php ... $mysqli = new mysqli("localhost", "user", "pass", "databaze"); ... $menu = new MojeMenu(); ... ---------------------------------- class MojeMenu { function __construct() { $query = 'SELECT id, nazev FROM menu ORDER BY poradi;'; $result = $mysqli->query($query); ... $result->close(); } } ---------------------------------- Vyhazuje to: Fatal error: Call to a member function query() on a non-object Když do __construct přidám: $mysqli = new mysqli("localhost", "user", "pass", "databaze"); Musím v každé třídě, která přistupuje k databázi vytvářet připojení k databázi (objekt $mysqli)? Děkuju za pomoc. CistiC |
||
Akacko Profil |
#2 · Zasláno: 18. 1. 2008, 13:43:31 · Upravil/a: Akacko
CistiC
sice nejsem v oop nějaký profik, ale myslím že by to šlo vyřešit pomoci děděni. Zkus tvořit třídu takto: class MojeMenu extends mysqli. a tento řádek potom jako takto $result = mysqli::query($query); Doufám že jsem nenapsal nějakou blbost. |
||
BetaCam Profil |
#3 · Zasláno: 18. 1. 2008, 13:54:25
Akacko
CistiC sice nejsem v oop nějaký profik, ale myslím že by to šlo vyřešit pomoci děděni. Zkus tvořit třídu takto: class MojeMenu extends mysqli. V žádném případě tohle nedělej. Dědění je sice krásná věc ale mělo by se dodržovat pravidlo, že potomek je specialní případ rodiče. Stejně tak potomek by měl umět zastat funkci rodiče. |
||
CistiC Profil * |
#4 · Zasláno: 18. 1. 2008, 14:16:47
Vyreseno.
Staci si zpristupnit $mysqli uvnitr te tridy pomoci global. |
||
BetaCam Profil |
#5 · Zasláno: 18. 1. 2008, 14:21:48
CistiC
začínam s oop a hned jsem narazil na problém a nevím, jaké je správné řešení. Mimochodem řešení existuje spousta jenže většina tech řešení se odvozuje podle toho jak je navržená aplikace jako taková. Je těžké navrhovat tu nejaké řešení, když nevíme jak máš koncipovanou aplikaci. Každopáně by ses měl drzet toho co jsem psal v předchozím postu. A navíc ve většině případů je lepší třídy složit než je dědit. |
||
BetaCam Profil |
#6 · Zasláno: 18. 1. 2008, 14:23:06 · Upravil/a: BetaCam
CistiC
Staci si zpristupnit $mysqli uvnitr te tridy pomoci global. To mi nepřipadá zrovna jako nejoriginálnější řešení. :) |
||
orsic Profil |
#7 · Zasláno: 18. 1. 2008, 15:07:50
To mi nepřipadá zrovna jako nejoriginálnější řešení. :)
a jaké by tedy bylo originelní řešení ?? |
||
lucas Profil * |
#8 · Zasláno: 18. 1. 2008, 15:43:20
napriklad v triede budes mat private $sql_spojenie a cez konstruktor uz len vlozis raz vytvorene spojenie to objektu.
|
||
BetaCam Profil |
#9 · Zasláno: 18. 1. 2008, 16:12:36
orsic
Záleží na povaze aplikace. Sem zvyklej dělat aplikace jako MVC proto mi to přijde jako pro mě "divné" řešení. CistiC má svou třídu pojmenovanou jako MojeMenu z čehož se dá usuzovat, že by to v podstatě měl být nějaký view. Už jen to, že se view se stará o to co by měl dělat Model mi přijde divné, ale jak říkám si je to tím, že sem příliš zvyklí na MVC. a jaké by tedy bylo originelní řešení ?? Způsobu je hromada. Od parameru až po zdědění třídy v nějaké logické hierarchii tříd. A popravdě mě OOP a používání globálních proměnných moc k sobě nepasuje. :) |
||
Mastodont Profil |
#10 · Zasláno: 18. 1. 2008, 17:05:17 · Upravil/a: Mastodont
Jestli ta třída MojeMenu slouží ke generování nabídky (jak odhaduji), tak já bych jí $result předal v konstruktoru nebo jako parametr metody. Dotaz a načítání dat úplně oddělit.
echo $Formatter:getTable($DAO->getSomeRows($table, $fields, $where)); Asi takto to mám já. Metoda getSomeRows vrací result, getTable hotovou HTML tabulku. |
||
BetaCam Profil |
#11 · Zasláno: 18. 1. 2008, 17:52:35
Mastodont
No jenže tenhle příklad vyplívá z větší či menší části z návrhu tvé aplikace. Je otázka jestli CistiC, který píše, že s OOP začíná má vůbec návrh a strukturu aplikace. |
||
Mastodont Profil |
#12 · Zasláno: 18. 1. 2008, 18:21:16
BetaCam
To asi má, pochybuji, že by psal třídu pro menu, která by nebyla do ničeho zasazena. Na otázku Musím v každé třídě, která přistupuje k databázi vytvářet připojení k databázi (objekt $mysqli)? odpovídám takto: takovou třídu si udělej jen jednu. (Další možnost je třeba singleton vracející handle připojení, který je předáván do dalších tříd dle potřeby. Známá věc, která se dá lehce vygooglit.) |
||
BetaCam Profil |
#13 · Zasláno: 18. 1. 2008, 18:52:07
Mastodont
To asi má, pochybuji, že by psal třídu pro menu, která by nebyla do ničeho zasazena. Ani bych se nedivil kdyby nebyla. :) Vetšina začátečníků s OOP má pocit, že OOP je o uzavření kódu do tříd. Na prvotní návrh kašlou. Až když začnou opravdu "myslet" a OO programovat začnou aplikaci navrhovat v pravém smyslu OOP. Třeba sou mé názory pomýlené a možná zbytečně CistiCe podceňuji, ale většinou, když se setkám s aplikací od OOP začátečníka tak to má s OOP opravdu společného snad jen to slovo class. :) |
||
Mastodont Profil |
#14 · Zasláno: 18. 1. 2008, 19:33:36
Vetšina začátečníků s OOP má pocit, že OOP je o uzavření kódu do tříd.
Známá věc :-))) //index.php $app = new Application(); $app->Start(); ... |
||
Časová prodleva: 1 rok
|
|||
radekzatec Profil |
#15 · Zasláno: 7. 4. 2009, 19:32:32
neni to ma práce ale inspirace to myslim bude kazdej si upravi dle vlastních potreb
<?php // soubor heslo.php $mysqluzivatel="user"; // jméno uživatele pro přístup k MySQL $mysqlheslo="paswd"; // heslo $mysqlhost="localhost"; // název počítače, na kterém běží MySQL $mysqldb="nazev_DB"; // název databáze ?> <?php // Kvůli lepšímu zabezpečení přesuňte heslo.php do složky, // která není přístupná z WWW a upravte cestu k souboru // v require.once class MojeDb { protected $mysqli; protected $zobrazitchyby = TRUE; // nastavte na FALSE, pokud nechcete vidět chybové zprávy protected $zobrazitsql = FALSE; // nastavte na TRUE, pokud chcete při ladění vidět všechny dotazy SQL protected $sqlpocitadlo = 0; // počitadlo pro příkazy SQL protected $radkypocitadlo = 0; // počitadlo pro vrácené řádky SELECTů protected $dbcas = 0; // počitadlo času pro provedení dotazů protected $pocatecnicas; // konstruktor function __construct() { require_once('heslo.php'); $this->mysqli = @new mysqli($mysqlhost, $mysqluzivatel, $mysqlheslo, $mysqldb); // bylo připojení navázáno v pořádku? if(mysqli_connect_errno()) { $this->tiskchyby("Nepodařilo se navázat připojení! (" . mysqli_connect_error() . ")"); // sem je možné doplnit HTML // pro ukončení stránky (</body></html> apod.) $this->mysqli = FALSE; exit(); } $this->pocatecnicas = $this->microtime_jako_float(); } // destruktor function __destruct() { $this->close(); } // explicitní uzavření function close() { if($this->mysqli) $this->mysqli->close(); $this->mysqli = FALSE; } function odkaznaMysqli() { return $this->mysqli; } // spuštění dotazu SELECT, vrácení pole function dotazPoleObjektu($sql) { $this->sqlpocitadlo++; $this->tisksql($sql); $cas1 = $this->microtime_jako_float(); $vysledek = $this->mysqli->query($sql); $cas2 = $this->microtime_jako_float(); $this->dbcas += ($cas2 - $cas1); if($vysledek) { if($vysledek->num_rows) { $vysledek_array = array(); while($radek = $vysledek->fetch_object()) $vysledek_array[] = $radek; $this->radkypocitadlo += sizeof($vysledek_array); return $vysledek_array; } else return FALSE; } else { $this->tiskchyby($this->mysqli->error); return FALSE; } } // spuštění dotazu SELECT, vrácení pole function dotazPole($sql) { $this->sqlpocitadlo++; $this->tisksql($sql); $cas1 = $this->microtime_jako_float(); $vysledek = $this->mysqli->query($sql); $cas2 = $this->microtime_jako_float(); $this->dbcas += ($cas2 - $cas1); if($vysledek) { if($vysledek->num_rows) { $vysledek_array = array(); while($radek = $vysledek->fetch_array()) $vysledek_array[] = $radek; $this->radkypocitadlo += sizeof($vysledek_array); return $vysledek_array; } else return FALSE; } else { $this->tiskchyby($this->mysqli->error); return FALSE; } } // spuštění dotazu SELECT, který vrací jen jednu // položku (například SELECT COUNT(*) FROM tabulka); // vrátí tuto položku // pozor: při výskytu chyby vrátí -1, nikoli 0! function dotazJednaPolozka($sql) { $this->sqlpocitadlo++; $this->tisksql($sql); $cas1 = $this->microtime_jako_float(); $vysledek = $this->mysqli->query($sql); $cas2 = $this->microtime_jako_float(); $this->dbcas += ($cas2 - $cas1); if($vysledek) { if ($radek=$vysledek->fetch_array()) { $vysledek->close(); $this->radkypocitadlo++; return $radek[0]; } else { // dotaz nevrátil žádná data return -1; } } else { $this->tiskchyby($this->mysqli->error); return -1; } } // spuštění příkazu SQL, který nevrací data function provest($sql) { $this->sqlpocitadlo++; $this->tisksql($sql); $cas1 = $this->microtime_jako_float(); $vysledek = $this->mysqli->real_query($sql); $cas2 = $this->microtime_jako_float(); $this->dbcas += ($cas2 - $cas1); if($vysledek) return TRUE; else { $this->tiskchyby($this->mysqli->error); return FALSE; } } // zjištění insert_id po příkazu INSERT function vlozeneId() { return $this->mysqli->insert_id; } // vložení \ před ', " atd. function escape($text) { return trim($this->mysqli->escape_string($text)); } // vrátí 'NULL' or '<uvozovkovaný řetězec>' function sql_retezec($text) { if(!$text || trim($text)=="") return 'NULL'; else return "'" . $this->escape(trim($text)) . "'"; } function error() { return $this->mysqli->error; } private function tisksql($sql) { if($this->zobrazitsql) printf("<p><font color=\"#0000ff\">%s</font></p>\n", htmlspecialchars($sql)); } private function tiskchyby($text) { if($this->zobrazitchyby) printf("<p><font color=\"#ff0000\">%s</font></p>\n", htmlspecialchars($text)); } function zobrazitStatistiku() { $totalTime = $this->microtime_jako_float() - $this->pocatecnicas; printf("<p><font color=\"#0000ff\">Příkazy SQL: %d\n", $this->sqlpocitadlo); printf("<br />Celkem vráceno řádků: %d\n", $this->radkypocitadlo); printf("<br />Celková doba provádění dotazů (MySQL): %f\n", $this->dbcas); printf("<br />Celková doba zpracování (PHP): %f\n", $totalTime - $this->dbcas); printf("<br />Celkový čas od posledního vytvoření/vynulování objektu MojeDB: %f</font></p>\n", $totalTime); } function vynulovatStatistiku() { $this->sqlpocitadlo = 0; $this->radkypocitadlo = 0; $this->dbcas = 0; $this->pocatecnicas = $this->microtime_jako_float(); } private function microtime_jako_float() { list($usek, $sek) = explode(" ", microtime()); return ((float)$usek + (float)$sek); } } |
||
AM_ Profil |
#16 · Zasláno: 7. 4. 2009, 20:16:08
Když už píšete třídu pro rozšířenou obsluhu MySQL, není lepší to psát řekněme jako dědice třídy mysqli? Nejsem zas tak ostřílený objektař, ale přijde mi to logičtější i jednodušší.
|
||
fuckin Profil * |
#17 · Zasláno: 7. 4. 2009, 21:15:07
Am_
V zadnem pripade, trida mysqli je zbytecne komplexni a zbytecne by v tom udelala bordel, ceho bys ti jako dosahl? Vzdy se dela oop trida pro db, nikdy jsem vsak nevidel jako dedice mysqli. A logictejsi ci jednodussi to neni... |
||
AM_ Profil |
#18 · Zasláno: 7. 4. 2009, 21:18:35
No stejne ji pouzijes, tak mas po ni dedit nebo psat tridu jejiz clenskou promennou bude odkaz na instanci mysqli? Zalezi tedy, na co to chces pouzit:
1-jako univerzalni rozhrani s DB (az web pobezi na jine DB, trida se da prepsat) - pak ano, zvlast tridu 2-jako rozsireni funkcionality mysqli o ruzne zlepsovaky - neni duvod po ni nededit. Proc by to, ze je sama o sobe komplexni, melo byt duvod? A hlavne pak mas instanci jedne tridy, a ne instanci tve tridy s pridelenim clena instance mysqli tridy. |
||
Časová prodleva: 1 rok
|
|||
rixi Profil |
#19 · Zasláno: 30. 7. 2010, 20:51:54 · Upravil/a: rixi
k tejto tebe ak som dobre pochopil, tak pri connecte sa vyuziva inicializacia triedy mysqli a pri spracovavani vysledkov, konkretne mysqli->query vytvori a vyuziva dalsiu triedu a to mysqli_result, je tak? ak ano, v php manualu som o tom, co funkcia vracia, nic take nenasiel. otazka znie ci su moje uvahy spravne a ze preco sa to v manualu o tom nespomina. vychadza princip z toho, ze by na to mal prist clovek sam?
tiez nie som v oop zdatny, takze nie som si isty, ci som to dobre pochopil a tak sa za pripadne "blaboly" ospravedlnujem. d |
||
Časová prodleva: 13 let
|
0