Autor | Zpráva | ||
---|---|---|---|
Pinqui Profil |
#1 · Zasláno: 8. 7. 2009, 11:16:54 · Upravil/a: Pinqui
Dobrý den pokusil jsem se napsat třídu na tvoření elementů 'samozřejmě že v ní nejde vytvořit vše jako odkaz a obrázek např), ale zajímalo by mě zda ta třída pomůže, jestli je dobře napsaná, nebo jak ji napsat lépe, prostě hlavně všeobecné názory. OOP se snažím pochopit tak zkouším na příkladech děkuji.
<?php class Element { # vlozeni noveho elementu function add($element, $id = false, $clas = false, $text = false, $close = false) { $this->element[] = $element; $this->id[] = $id; $this->clas[] = $clas; $this->text[] = $text; $this->close[] = $close; } # zobrazeni polozky function showElement($x) { print "<{$this->element[$x]}"; if($this->id[$x]!=false) {print " id=\"{$this->id[$x]}\"";} if($this->clas[$x]!=false){print " class=\"{$this->clas[$x]}\"";} print ">\n{$this->text[$x]}"; if($this->close[$x]==true){print "</{$this->element[$x]}>\n";} } function closeElement($x){ print "</{$x}>"; } # vypsani elementu na stranku function show() { for ($x = 0; $x < count($this->element); $x++) { $this->showElement($x); } } } $el = new Element; $el->add('div', 'testid'); $el->add('span', false, 'testclass', false, true); $el->show(); $el->closeElement('div'); ?> |
||
Mastodont Profil |
#2 · Zasláno: 8. 7. 2009, 11:24:02 · Upravil/a: Mastodont
$el->add('span', false, 'testclass', false, true); Osobně bych u funkcí s větším množstvím nepovinných parametrů použil předávání formou pole a mergnul předané hodnoty s výchozími. Stačí pak zadat jen ty hodnoty, které chci změnit vůči výchozím. function add($element, $options) { $defaults = Array ( 'id' => 0, 'class' => 0, 'text' => 0, 'close' = 0); ... $this->options = array_merge($defaults, $options); } ... $el->add('span', Array('class' => 'testclass'); |
||
Pinqui Profil |
#3 · Zasláno: 8. 7. 2009, 12:45:28
A bude to mít nějaký efekt ve větším projektu použít třídu k tvoření elementů? Nějakou výhodu, aby třeba nebylo spíše na obtíž uživat třídu pro tvorbu elementů, aby to nespomalovalo práci s kódama.?? Díky
|
||
Mastodont Profil |
#4 · Zasláno: 8. 7. 2009, 12:52:31
No to si musíš vyřešit sám, jak chceš vytvářet HTML ... možností je spousta.
|
||
fuckin Profil |
#5 · Zasláno: 8. 7. 2009, 19:18:31
mezi dobre zvyky patri pouzivat viditelnost u vseho napr : public function ahoj(), to same plati i u promennych napr protected $promenna atd.
Dale kdyz nepouzijes konstruktor tak bys ho mel vynulovat public function __construct() {} Jestli nasels navody pro php 4 tak je rovnou zahod, php 5 mnohonasobne vylepsilo oop tak nepouzivej stare zpusoby. |
||
Pinqui Profil |
#6 · Zasláno: 8. 7. 2009, 20:17:10 · Upravil/a: Pinqui
Mastodont
Nějak nevím, když jsem to změnil, jak změnit zbytek ködu aby mi to fungovalo.. Nechce se mi to totiž vypsat :-( // po změně ty add funkce jak jsi psal |
||
joe Profil |
#7 · Zasláno: 8. 7. 2009, 22:58:08
Můj názor: takovéhle programování fakt "miluju". Proč sakra píše někdo něco takovýho, když musí dopředu vědět, že to je naprosto nepoužitelný a zbytečný? Není jednodušší napsat echo "<div class='trida'>"; ?
Ke kódu: Nezdá se mi moc tvé pojmenování proměnných element[] bych nazval spíše elements[], protože jich je více, ale to je každého věc class se píše s dvěma s ukončovací element - máš pocit, že ukončovací element může být jiný než otevírací (když beru v úvahu jen párové elementy) u showElement() nemáš oveření, jestli element vůbec existuje A když to mám celkově zhodnotit, tak mi přijde, že si spíš přiděláváš víc práce, než naopak - zbytečně ztracený čas a čas jsou peníze ;) |
||
Pinqui Profil |
#8 · Zasláno: 9. 7. 2009, 10:20:47
joe
close - uzavření (to jsem ěml, kdybych chtěl do toho elementu vkládat další věci. Jinak tuto třídu nemám v úmyslu použít, jen se na ní zkouším naučit, jak to pracuje. Nějak mě nenapadl jiný nápad zrovna. clas jsem psal jednou když jsem napsal $this->class tak to class sčernalo a asi by to mohlo dělat nepořádek. jak případně ověřím, jestli element existuje? |
||
DoubleThink Profil * |
#9 · Zasláno: 9. 7. 2009, 11:34:39
„zajímalo by mě zda ta třída pomůže“
Moc ne, v tomto případě je jednodušší napsat tag přímo. A žádné další výhody třída nepřináší. „mezi dobre zvyky patri pouzivat viditelnost u vseho napr : public function ahoj()“ public je implicitní hodnota, nemusí být explicitně definována. „Dale kdyz nepouzijes konstruktor tak bys ho mel vynulovat“ Zbytečné. Neuvedený konstruktor rovná se prázdný konstruktor. |
||
Jan Tvrdík Profil |
#10 · Zasláno: 9. 7. 2009, 12:23:57
DoubleThink:
„public je implicitní hodnota, nemusí být explicitně definována.“ To ano, přesto někteří programátoři (joe, Já…) považují za chybu, když se ten modifikátor neuvede. Pinqui: „zajímalo by mě, zda ta třída pomůže“ Vzhledem k tomu, jak je napsaná, tak ti práci nijak neusnadní. Pokud se ale podobná třída napíše dobře, tak dokáže usnadnit spoustu práce. |
||
DoubleThink Profil * |
#11 · Zasláno: 9. 7. 2009, 13:57:14
„To ano, přesto někteří programátoři (joe, Já…) považují za chybu, když se ten modifikátor neuvede. “
A někteří lidé si zase padesátkrát denně umývají ruce, co naděláš. Já identifikátor viditelnosti přidávám vždycky, ale jenom proto, že to za mě dělá editor. Netrápí mě, když není definován. |
||
Jack06 Profil |
#12 · Zasláno: 9. 7. 2009, 18:35:10 · Upravil/a: Jack06
Použil jsem kód na připojení a práci s mysqli, ale ne uplně z příkladu.. upraveno je připojení k databázi, problém $this->mysqli prosím o radu díky
<?php header('Content-Type: text/html; charset=utf-8'); /* ================================= USE MySQLi ============================= */ class MyDB extends MySQLi { protected $mysqli; protected $showerror = TRUE; // nastavte FALSE, pokud nechcete zobrazovat chybová hlášení protected $showsql = FALSE; // nastavte TRUE, pokud chcete kvůli ladění zobrazovat všechny dotazy SQL protected $sqlcounter = 0; // počítadlo příkazů SQL protected $rowcounter = 0; // počítadlo vrácených řádků SELECT protected $dbtime = 0; // počítadlo času potřebného pro vykonání dotazů protected $starttime; private static $_instance = null; const SERVER = 'localhost'; const USERNAME = 'root'; const PASSWORD = 'xxx'; const DBNAME = 'xxx'; private function __construct() { $this->mysqli = parent::__construct(self::SERVER, self::USERNAME, self::PASSWORD, self::DBNAME); } public static function _() { if(self::$_instance === null) { self::$_instance = new self(); } //$this->starttime = $this->microtime_float(); return self::$_instance; } // dodatečné uzavření public function close() { if($this->mysqli) $this->mysqli->close(); $this->mysqli = FALSE; } public function getMysqli() { return $this->mysqli; } // vykonání dotazu SELECT, vrací se pole public function queryObjectArray($sql) { $this->sqlcounter++; $this->printsql($sql); $time1 = $this->microtime_float(); $result = $this->mysqli->query($sql); $time2 = $this->microtime_float(); $this->dbtime += ($time2 - $time1); if($result) { if($result->num_rows) { while($row = $result->fetch_object()) $result_array[] = $row; $this->rowcounter += sizeof($result_array); return $result_array; } else return FALSE; } else { $this->printerror($this->mysqli->error); return FALSE; } } // vykonání dotazu SELECT, vrací se pole public function queryArray($sql) { $this->sqlcounter++; $this->printsql($sql); $time1 = $this->microtime_float(); $result = $this->query($sql); $time2 = $this->microtime_float(); $this->dbtime += ($time2 - $time1); if($result) { if($result->num_rows) { while($row = $result->fetch_array()) $result_array[] = $row; $this->rowcounter += sizeof($result_array); return $result_array; } else return FALSE; } else { $this->printerror($this->mysqli->error); return FALSE; } } // vykonání dotazu SELECT, který vrací pouze jednu položku // (tj. SELECT COUNT(*) FROM table); vrací // tuto položku // pozor: tato metoda při chybě vrací hodnotu -1 (a nikoliv 0)! public function querySingleItem($sql) { $this->sqlcounter++; $this->printsql($sql); $time1 = $this->microtime_float(); $result = $this->mysqli->query($sql); $time2 = $this->microtime_float(); $this->dbtime += ($time2 - $time1); if($result) { if ($row=$result->fetch_array()) { $result->close(); $this->rowcounter++; return $row[0]; } else { // dotaz nevrátil žádná data return -1; } } else { $this->printerror($this->mysqli->error); return -1; } } // vykonání příkazu SQL bez výsledků (žádný dotaz) public function execute($sql) { $this->sqlcounter++; $this->printsql($sql); $time1 = $this->microtime_float(); $result = $this->mysqli->real_query($sql); $time2 = $this->microtime_float(); $this->dbtime += ($time2 - $time1); if($result) return TRUE; else { $this->printerror($this->mysqli->error); return FALSE; } } // použití insert_id za příkazem INSERT public function insertId() { return $this->mysqli->insert_id; } // vložení \ před ', " atd. public function escape($txt) { return trim($this->mysqli->escape_string($txt)); } // vrací hodnotu 'NULL' nebo '<quoted string>' public function sql_string($txt) { if(!$txt || trim($txt)=="") return 'NULL'; else return "'" . $this->escape(trim($txt)) . "'"; } public function error() { return $this->mysqli->error; } private function printsql($sql) { if($this->showsql) printf("<p><font color=\"#0000ff\">%s</font></p>\n", htmlentities($sql)); } private function printerror($txt) { if($this->showerror) printf("<p><font color=\"#ff0000\">%s</font></p>\n", htmlentities($txt)); } public function showStatistics() { $totalTime = $this->microtime_float() - $this->starttime; printf("<p><font color=\"#0000ff\">Příkazy SQL: %d\n", $this->sqlcounter); printf("<br />Součet vracených řádků: %d\n", $this->rowcounter); printf("<br />Čas vykonávání dotazů (MySQL): %f\n", $this->dbtime); printf("<br />Doba zpracování (PHP): %f\n", $totalTime - $this->dbtime); printf("<br />Celkový čas od vytvoření MyDB / poslední reset: %f</font></p>\n", $totalTime); } public function resetStatistics() { $this->sqlcounter = 0; $this->rowcounter = 0; $this->dbtime = 0; $this->starttime = $this->microtime_float(); } private function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } } ?> zadám: <?php $db = MyDB::_(); $db->set_charset('utf8'); // zjitšění počtu sekcí $sql = "SELECT COUNT(*) FROM test"; $n = $db->querySingleItem($sql); echo "<p>Tabulka se sekcemi obsahuje $n položek.</p>\n"; ?> a hodí mi to chybu: Fatal error: Call to a member function query() on a non-object in C:\Software\VertrigoServ\www\prace\sp new\class\MyDB.php on line 99 původní připojení k mysqli bylo: function __construct() { require_once('password.php'); $this->mysqli = @new mysqli($mysqlhost, $mysqluser, $mysqlpasswd, $mysqldb); // je připojení v pořádku? if(mysqli_connect_errno()) { $this->printerror("Spojení nebylo navázáno! (" . mysqli_connect_error() . ")"); $this->mysqli = FALSE; exit(); } $this->starttime = $this->microtime_float(); } // destruktor function __destruct() { $this->close(); } Díky |
||
joe Profil |
#13 · Zasláno: 9. 7. 2009, 19:32:35 · Upravil/a: joe
Zkus si napsat třeba místo tohoto řádku (v querySingleItem())
$result = $this->mysqli->query($sql); tohle var_dump($this->mysqli); Co ti to napsalo? Skutečně je v mysqli objekt? Proč to konec konců nevoláš takhle $db = new MyDB(); $db->set_charset('utf8'); // zjitšění počtu sekcí $sql = "SELECT COUNT(*) FROM test"; $n = $db->querySingleItem($sql); echo "<p>Tabulka se sekcemi obsahuje $n položek.</p>\n"; Nechápu využití metody _() --- Jinak chápu, člověk se to musí někde naučit, jen doufám, že takové věci nehodláš používat :-) S tím class/clas jsem si říkal, že tam asi bude problém. Ověříš to tak, že otestuješ, jestli v poli je položka obsažená. Při zapnutí hlášení chyb by to vyvolalo Notice, kdyby v poli nebyla, takže if(isset(element[$x])) { // existuje Jan Tvrdík „přesto někteří programátoři (joe, Já…) považují za chybu“ Tvrdil jsem to někde? :-) Možná jo - teď si nevzpomínám, ale teď to za chybu nepovažuju, jen mi přijde přehlednější to tam uvádět „Vzhledem k tomu, jak je napsaná, tak ti práci nijak neusnadní. Pokud se ale podobná třída napíše dobře, tak dokáže usnadnit spoustu práce.“ Je možné, že třída je napsaná dobře, ale ulehčí ti fakt čas a psaní, tedy je k něčemu? S Nette jsem si chvíli hrál, tak o něm něco vím, ale přesto mi tahle třída přijde zbytečná a jednodušší je napsat vypis('<element attribute="value">...</element>'). Možná, že to má nějaké využití při AJAXu, to nevím, ale i tak, mi to přijde zbytečné psát místo jediného řádku pro výpis řádků 602 a pak se ještě s tím nějaký čas učit, jak že se to má vlastně napsat, aby to vypsalo to, co chci. |
||
Aesir Profil |
#14 · Zasláno: 9. 7. 2009, 19:50:30
joe:
„Nechápu využití metody _() “ Hledejte návrhový vzor singleton. „přesto mi tahle třída přijde zbytečná“ většinou se podobné používají pro generování dynamických věcí (například formulářů) u nichž potřebujete dělat častěji změny společných věcí na jednom místě |
||
joe Profil |
#15 · Zasláno: 9. 7. 2009, 20:05:36
Aesir
singleton chápu, pravda, nevím u čeho jsem se zarazil. „většinou se podobné používají pro generování dynamických věcí (například formulářů) u nichž potřebujete dělat častěji změny společných věcí na jednom místě“ Tam to asi využití má, ale postupoval bych jiným způsobem, pro mě lepším, "šablonami" v tomto případě. |
||
Aesir Profil |
#16 · Zasláno: 9. 7. 2009, 20:30:22
joe:
„pro mě lepším, "šablonami" v tomto případě“ I to je způsob, pokud vám nevadí míchání aplikační logiky do šablon. |
||
Jack06 Profil |
#17 · Zasláno: 9. 7. 2009, 20:39:14
joe
Původní funkční kód je: <?php class MyDb { protected $mysqli; protected $showerror = TRUE; // nastavte FALSE, pokud nechcete zobrazovat chybová hlášení protected $showsql = FALSE; // nastavte TRUE, pokud chcete kvůli ladění zobrazovat všechny dotazy SQL protected $sqlcounter = 0; // počítadlo příkazů SQL protected $rowcounter = 0; // počítadlo vrácených řádků SELECT protected $dbtime = 0; // počítadlo času potřebného pro vykonání dotazů protected $starttime; // konstruktor function __construct() { require_once('password.php'); $this->mysqli = @new mysqli($mysqlhost, $mysqluser, $mysqlpasswd, $mysqldb); // je připojení v pořádku? if(mysqli_connect_errno()) { $this->printerror("Spojení nebylo navázáno! (" . mysqli_connect_error() . ")"); // sem můľete přidat výstup pro kód HTML pro uzavření stránky // (</body></html> apod.) $this->mysqli = FALSE; exit(); } $this->starttime = $this->microtime_float(); } // destruktor function __destruct() { $this->close(); } // dodatečné uzavření function close() { if($this->mysqli) $this->mysqli->close(); $this->mysqli = FALSE; } function getMysqli() { return $this->mysqli; } // vykonání dotazu SELECT, vrací se pole function queryObjectArray($sql) { $this->sqlcounter++; $this->printsql($sql); $time1 = $this->microtime_float(); $result = $this->mysqli->query($sql); $time2 = $this->microtime_float(); $this->dbtime += ($time2 - $time1); if($result) { if($result->num_rows) { while($row = $result->fetch_object()) $result_array[] = $row; $this->rowcounter += sizeof($result_array); return $result_array; } else return FALSE; } else { $this->printerror($this->mysqli->error); return FALSE; } } // vykonání dotazu SELECT, vrací se pole function queryArray($sql) { $this->sqlcounter++; $this->printsql($sql); $time1 = $this->microtime_float(); $result = $this->mysqli->query($sql); $time2 = $this->microtime_float(); $this->dbtime += ($time2 - $time1); if($result) { if($result->num_rows) { while($row = $result->fetch_array()) $result_array[] = $row; $this->rowcounter += sizeof($result_array); return $result_array; } else return FALSE; } else { $this->printerror($this->mysqli->error); return FALSE; } } // vykonání dotazu SELECT, který vrací pouze jednu poloľku // (tj. SELECT COUNT(*) FROM table); vrací // tuto poloľku // pozor: tato metoda při chybě vrací hodnotu -1 (a nikoliv 0)! function querySingleItem($sql) { $this->sqlcounter++; $this->printsql($sql); $time1 = $this->microtime_float(); $result = $this->mysqli->query($sql); $time2 = $this->microtime_float(); $this->dbtime += ($time2 - $time1); if($result) { if ($row=$result->fetch_array()) { $result->close(); $this->rowcounter++; return $row[0]; } else { // dotaz nevrátil ľádná data return -1; } } else { $this->printerror($this->mysqli->error); return -1; } } // vykonání příkazu SQL bez výsledků (ľádný dotaz) function execute($sql) { $this->sqlcounter++; $this->printsql($sql); $time1 = $this->microtime_float(); $result = $this->mysqli->real_query($sql); $time2 = $this->microtime_float(); $this->dbtime += ($time2 - $time1); if($result) return TRUE; else { $this->printerror($this->mysqli->error); return FALSE; } } // pouľití insert_id za příkazem INSERT function insertId() { return $this->mysqli->insert_id; } // vloľení \ před ', " atd. function escape($txt) { return trim($this->mysqli->escape_string($txt)); } // vrací hodnotu 'NULL' nebo '<quoted string>' function sql_string($txt) { if(!$txt || trim($txt)=="") return 'NULL'; else return "'" . $this->escape(trim($txt)) . "'"; } function error() { return $this->mysqli->error; } private function printsql($sql) { if($this->showsql) printf("<p><font color=\"#0000ff\">%s</font></p>\n", htmlentities($sql)); } private function printerror($txt) { if($this->showerror) printf("<p><font color=\"#ff0000\">%s</font></p>\n", htmlentities($txt)); } function showStatistics() { $totalTime = $this->microtime_float() - $this->starttime; printf("<p><font color=\"#0000ff\">Příkazy SQL: %d\n", $this->sqlcounter); printf("<br />Součet vracených řádků: %d\n", $this->rowcounter); printf("<br />Čas vykonávání dotazů (MySQL): %f\n", $this->dbtime); printf("<br />Doba zpracování (PHP): %f\n", $totalTime - $this->dbtime); printf("<br />Celkový čas od vytvoření MyDB / poslední reset: %f</font></p>\n", $totalTime); } function resetStatistics() { $this->sqlcounter = 0; $this->rowcounter = 0; $this->dbtime = 0; $this->starttime = $this->microtime_float(); } private function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } } // připojení k MySQL $db = new MyDb(); // zjitšění počtu sekcí $sql = "SELECT COUNT(*) FROM categories"; $n = $db->querySingleItem($sql); echo "<p>Tabulka se sekcemi obsahuje $n poloľek.</p>\n"; ?> A to funguje. Proč to konec konců nevoláš takhle :... // private function __construct() // třídu MySQLi nemám nikde napsanou tu si to bere ani nevím odkud samo |
||
Aesir Profil |
#18 · Zasláno: 9. 7. 2009, 21:01:51
Jack06:
„třídu MySQLi nemám nikde napsanou tu si to bere ani nevím odkud samo“ Je to rozšíření PHP, což může být jedním z důvodů té chyby, která všeobecně znamená, že se snažíte volat metodu nad něčím, co není objektem. Dejte na radu v [#13] |
||
Jack06 Profil |
#19 · Zasláno: 9. 7. 2009, 21:08:20
Kdybych chtěl aktuální připojení k mysql ošetřit taky aby se provedlo jen jednou tak to zapouzdřím stejně jako tu třídu co nefunguje
|
||
joe Profil |
#20 · Zasláno: 9. 7. 2009, 21:37:16
Aesir
„I to je způsob, pokud vám nevadí míchání aplikační logiky do šablon.“ Ne, nezdá se mi, že bych tím míchal aplikační logiku do šablon. Šablona by zůstala šablonou, třeba pro zmíněný formulář by se v šabloně jen iterovalo (např.) a vypisovaly se nějaká data. Naopak si myslím, že pokud se vytvoří třída pro generování některých elementů (viz Nette), tak se tím míchají šablony s aplikační logikou. Pro mě je tedy lepší když v šabloně hned vidím, co bude výsledkem a na nějaké místa si vypíšu data, než neurčitou dobu zkoumat, co mi z toho vlastně vyleze. ad singleton. Už vím proč jsem to napsal, pokud se teď nepletu, jde to napsat i bez té metody, aby to byl singleton. Já si to tak podobně píšu. Jack06 Tak teď tě nechápu, proč tedy nevyužiješ toho co funguje? :-) Je to kvůli tomu, aby se ti pokaždý nepřipojovalo k db nebo proč to chceš mít jinak než ten kód, který funguje? |
||
Jack06 Profil |
#21 · Zasláno: 9. 7. 2009, 22:41:08
joe
Potřebuji, aby se instance připojení k mysqli vytvořila jen jednom aby byla menší zátěž na databázi. když budu refreshovat stránku s připojením k databázi dejme tomu často viz chatová místnost každých 5-20 vteřin, tak to bude pořád zatěžovat databázi není-li tak?? Vím že mi to třebas občas npsalo něco o překročení maximálního počtu připojení k databázi.. po vytvoření této instance k připojení jne jednou se mi již hláška nezobrazila |
||
Časová prodleva: 5 dní
|
|||
Pinqui Profil |
#22 · Zasláno: 14. 7. 2009, 18:09:10
KOukám pěkně se tu rozvinula konverzace.
Mastodont Prosimtě ten příklad co jsí napsal mi hází chybu: Parse error: syntax error, unexpected '=', expecting ')' in C:\Software\VertrigoServ\tts\index.php on line 6 to je řádek: $defaults = Array ( 'id' => 0, 'class' => 0, 'text' => 0, 'close' = 0); NWM proč ...?? |
||
joe Profil |
#23 · Zasláno: 14. 7. 2009, 18:11:23
'close' => 0 |
||
Pinqui Profil |
#24 · Zasláno: 14. 7. 2009, 18:12:45
joe
ježiš ajo díky moc |
||
joe Profil |
#25 · Zasláno: 14. 7. 2009, 18:15:09
Jack06
S takovým dotazem jsi mě teď docela zaskočil :) sám nevím jak to pořádně funguje, ale řekl bych, že při každém načtení stránky se musí pokaždé připojit k databázi. Je třeba si uvědomit, že po žádosti se vykoná kód a ten pak skončí tím, že se zobrazí stránka (tj. tedy jako kdyby se spustil program, něco se provedlo a program se ukončil). Vím, že existuje persistentní připojení k databázi, ale už nevím jak funguje, zda se připojení někam uloží a pak se znovu nepřipojuje při další žádosti (?) - nezkoumal jsem to. Spíš si myslím, že problém byl, že jsi se připojoval k databázi vždycky, pokud jsi se na ni nějak dotazoval nebo ne? |
||
Časová prodleva: 15 let
|
0