
RimElek
VIP
|
"Még azt szeretném megkérdezni, hogy a "kész könyvtárak használata" alatt konkrétabban mikre gondoltál?"
Konkrétan még egyet sem használtam. Annak idején én is megírtam a magamét valamelyik keretrendszer "query builder"-ének mintájára. De annyira népszerű ez a megoldás, hogy tuti van keretrendszertől független is.
Van a Doctrine: Link
A QueryBuilder csak egy része. Elég profi eszköz, de pont akkor akartam elkezdeni, amikor más jött közbe.
És egy gyors keresés eredményeként találtam egy egyszerűbbet. PHP MySQL Query Builder: Link
A "PHP Query Builder" és hasonlókra keresve biztos találsz másokat is.
De eltértünk a tárgytól már.
|

Kolyok
Kezdő
|
"Akkor félre lettél vezetve általa. Ezért nem szabad megbízni mások osztályában sem. De arra jó volt, hogy felhívhattam a figyelmed, hogy hogy ne csináld :) "
Köszönöm még egyszer
Az alapértékek ill. ellenőrzésük és a hibák debugolását írogatom jelenleg. (A MAX_FILE_SIZE-os sor már ki lett véve - először nem is találtam aztán néztem meg itt az előző kódot)
Eközben dolgozok magán a rendszeren is (konkrétan a template rendszerén) ezért kissé lassan haladok ezzel a részével.
Még azt szeretném megkérdezni, hogy a "kész könyvtárak használata" alatt konkrétabban mikre gondoltál?
|

RimElek
VIP
|
"egy kész MySQL osztályt felhasználva fogtam hozzá"
Akkor félre lettél vezetve általa. Ezért nem szabad megbízni mások osztályában sem. De arra jó volt, hogy felhívhattam a figyelmed, hogy hogy ne csináld :)
"Az alap értékeket nem feltétlen szeretném megadni, inkább üzenetet küldök majd vissza a hiányzó/hibás indexről/adatról. "
Ha megfigyeled, én sem értelmes alapértéket adtam meg. Ez csak az ellenőrzést segíti. Nem kell és nem is nagyon tudsz értelmes értékeket megadni. De míg az eredeti osztályban szimpla paraméterek voltak, amik legalább léteztek, te tömbösre írtad. Amivel eggyel több problémád lett. Ezt küszöböli ki a javaslatom.
Még amit nem értek, az ez a sor az update-ben:
Ennek sincs sok értelme. Valószínűleg az lenne a célja, hogy ha egy az egyben átadod a $_POST tömböt feldolgozatlanul a "set"-nek, akkor a fájlfeltöltésnél megadható MAX_FILE_SIZE mezőt ne dolgozza fel. De ennek semmi keresni valója az adatbázis osztályában.
"Egyébként a sokkal több tanulás abszolút nem probléma."
Ha van bőven időd és a tanulás a cél, akkor jó is megdolgoztatni magad. De "felesleges" munka nélkül is lehet komolyan gondolni a célod. És az MVC terveidnek nem mond ellent kész könyvtárak használata sem. Abból is lehet tanulni, ötletet meríteni. És beépíteni a sajátodba.
Utoljára szerkesztette: RimElek 2013.05.28. 20:49
|

Kolyok
Kezdő
|
Hali!
Először is köszönöm a választ.
A topik nyitása után még pár módosítást végeztem és hozzádtam pár dolgot de sajnos azóta még nem volt időm rendesen átnézni.
Azt elfelejtettem az előző hozzászólásomban megemlíteni, hogy egy kész MySQL osztályt felhasználva fogtam hozzá (Forrás: PHP-MySQL-Class)
Innen jön igazából a tömb ellenőrzése és az 'operand' név is (nem sokat foglalkoztam még velük).
Az alap értékeket nem feltétlen szeretném megadni, inkább üzenetet küldök majd vissza a hiányzó/hibás indexről/adatról.
Szóval a jelenlegi kód ez lenne:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
<?php
class Database extends PDO {
public function __construct($dsn, $username, $password, $options) {
try {
parent::__construct($dsn, $username, $password, $options);
} catch (PDOException $e) {
echo 'Hiba: ' . $e->getMessage();
}
}
public function dbSelect($array) {
$query = 'SELECT ';
if ($array['select'] == '') {
$query .= '* FROM ' . $array['from'] . ' WHERE ';
}
else {
if(is_array($array['select']) && $array['select'] != '') {
foreach ($array['select'] as $key => $value) {
$query .= $value.', ';
}
$query = substr($query, 0, -2). ' FROM ' . $array['from'] . ' WHERE ';
}
else {
$query .= $array['select'] . ' FROM ' . $array['from'] . ' WHERE ';
}
}
if (is_array($array['where']) && $array['where'] != '') {
foreach ($array['where'] as $key => $value) {
if ($array['like']) {
$query .= $key . " LIKE :" . $key . " " . $array['operand'];
} else {
$query .= $key . " = :" . $key . " " . $array['operand'] . " ";
}
}
$query = substr($query, 0, -(strlen($array['operand']) + 2));
} else {
$query = substr($query, 0, -7);
}
if ($array['order'] != '') {
$query .= ' ORDER BY ' . $array['order'];
}
if ($array['limit'] != '') {
$query .= ' LIMIT ' . $array['limit'];
}
$prepared = $this->prepare($query);
$final = array();
if (is_array($array['where']) && $array['where'] != '') {
foreach ($array['where'] as $key => $value) {
if ($array['like']) {
$final[':' . $key] = '%'.$value.'%';
} else {
$final[':' . $key] = $value;
}
}
}
$prepared->execute($final);
$result = $prepared->fetchAll();
return $return;
}
public function dbInsert($array) {
if ($array['exclude'] == '') {
$array['exclude'] = array();
}
array_push($array['exclude'], 'MAX_FILE_SIZE');
$query = "INSERT INTO " . $array['table'] . " (";
foreach ($array['values'] as $key => $value) {
if (in_array($key, $array['exclude'])) {
continue;
}
$query .= $key . ', ';
}
$query = substr($query, 0, -2) . ') VALUES (';
foreach ($array['values'] as $key => $value) {
if (in_array($key, $array['exclude'])) {
continue;
}
$query .= ':' . $key . ', ';
}
$query = substr($query, 0, -2) . ')';
$prepared = $this->prepare($query);
$final = array();
foreach ($array['values'] as $key => $value) {
if (in_array($key, $array['exclude'])) {
continue;
}
$final[':' . $key] = $value;
}
$result = $prepared->execute($final);
$return = $prepared->rowCount();
return $return;
}
public function dbUpdate($array) {
if (trim($array['table']) == '' || !is_array($array['set']) || !is_array($array['where'])) {
return false;
}
if ($array['exclude'] == '') {
$array['exclude'] = array();
}
array_push($array['exclude'], 'MAX_FILE_SIZE');
$query = "UPDATE " . $array['table'] . " SET ";
foreach ($array['set'] as $key => $value) {
if (in_array($key, $array['exclude'])) {
continue;
}
$query .= $key . ' = :' . $key . ', ';
}
$query = substr($query, 0, -2);
$query .= ' WHERE ';
foreach ($array['where'] as $key => $value) {
$query .= $key . ' = :' . $key . ' AND ';
}
$query = substr($query, 0, -5);
$prepared = $this->prepare($query);
$finalSet = array();
foreach ($array['set'] as $key => $value) {
if (in_array($key, $array['exclude'])) {
continue;
}
$finalSet[':' . $key] = $value;
}
$finalWhere = array();
foreach ($array['where'] as $key => $value) {
if (in_array($key, $array['exclude'])) {
continue;
}
$finalWhere[':' . $key] = $value;
}
$final = array_merge($finalSet, $finalWhere);
$result = $prepared->execute($final);
$return = $prepared->rowCount();
return $return;
}
public function dbDelete($array) {
$query = "DELETE FROM ".$array['table']." WHERE ";
if (is_array($array['where']) && $array['where'] != '') {
foreach ($array['where'] as $key => $value) {
if ($array['like']) {
$query .= $key.' LIKE :'.$key.' AND ';
} else {
$query .= $key.' = :'.$key.' AND ';
}
}
$query = substr($query, 0, -5);
}
if ($array['limit'] != '') {
$query .= ' LIMIT ' . $array['limit'];
}
$prepared = $this->prepare($query);
$final = array();
if (is_array($array['where']) && $array['where'] != '') {
foreach ($array['where'] as $key => $value) {
if ($array['like']) {
$final[':' . $key] = '%'.$value.'%';
} else {
$final[':' . $key] = $value;
}
}
}
$result = $prepared->execute($final);
$return = $prepared->rowCount();
return $return;
}
}
?>
|
Ebben még úgyanúgy jelen vannak a hibás ellenőrzések a következő dolgom az lesz, hogy újraírom azokat.
Egyébként jelenleg csak egyszerű, alap lekérdezésekre használom a kódot, hogy kicsit megértsem/tanulmányozzam a lehetőségeket.
Példa:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$iArray = array('table'=>'ecms_users','values'=>array('id'=>'1','username'=>'test_user','email'=>'email@email.email','password'=>'sha512_salt_hash','salt'=>'salt'),'exclude'=>'');
$db->dbInsert($iArray);
$uArray = array('table'=>'ecms_users','set'=>array('email'=>'test@test.test'),'where'=>array('id'=>'1'),'exclude'=>'');
$db->dbUpdate($uArray);
$dArray = array('table'=>'ecms_users','where'=>array('username'=>'test_user'),'like'=>false ,'limit'=>'');
$db->dbDelete($dArray);
$sArray = array('select'=>'','from'=>'ecms_users', 'where'=>array('username'=>'test_user','email'=>'test@test.test'),'like'=>false,'operand'=>'AND','limit'=>'');
$db->dbSelect($sArray);
|
Számomra a fenti példák használata jobban átlátható/olvasható.
A debugolást is mindenképp átgondolom és a következő kódhoz hozzáadom.
Egyébként a sokkal több tanulás abszolút nem probléma. Határozottan szeretném véghez vinni az első hozzászólásban leírtakat még ha sok időmbe és tanulásba is kerül (elvégre ezek is az én előbbre jutásomat segítik)
Minden esetre köszönöm a választ próbálok majd minél jobban elmerülni a dologban és megérteni.
|

RimElek
VIP
|
Helló
Először is a PDO nem driver, hanem kiterjesztés. Esetleg osztálykönyvtár. Amit használhatsz különböző driverekkel:
http://www.php.net/manual/en/pdo.drivers.php
Te igazából teljesen feleslegesen örököltetsz a PDO osztályból, ugyanis sehol sem használod ki az öröklés tényét. Csak létrehozod a leszármazott osztály konstruktorában a PDO példányát és elmented egy "link" tulajdonságba. Miközben azzal, hogy példányosítod a Database osztályodat, már létrejött egy PDO példány, amire a $this kulcsszóval tudsz hivatkozni.
Saját konstruktorra így nem is lenne szükséged, de ha a kivételt mindenképpen el akarod kapni konstruktorban, akkor is elég a
1
| parent::__construct($dsn, $username, $password, $options) |
Nem kell semmilyen változónak átadni már semmit. Ezzel csak a szülő konstruktorát hívod. Ami azért kell, mert a saját konstruktoroddal elfedted az eredetit. Külön kell hivatkozni rá.
További tulajdonságokat is feleslegesen tárolsz. A kapcsolódási adatokra nincs is máshol szükséged, mint a konstruktorban.
PDO-tól független, de hibás, hogy ilyen ellenőrzésed van:
1
| if (is_array($array['where']) && $array['where'] != '') { |
Először megnézed, hogy tömb-e. De például mi van, ha nem is létezik a 'where' index? Az "isset"-tel tudnád ellenőrizni, hogy létezik-e. És még minden más művelet előtt kell. Az && utáni rész akkor fut csak le, ha az előző feltétel igaz volt. Vagyis a fenti példában, ha tömb volt az $array['where'], csak akkor nézed meg, hogy véletlenül nem egy üres string-e. Miközben tudod, hogy nem. Mindig igazat fog adni. Azt, hogy a tömb üres-e, nem így vizsgáljuk, hanem az "empty"-vel, vagy nézheted a hosszát a "count" függvénnyel, vagy nézheted, hogy egyenlő-e az üres tömbbel: array()
Így készíthetsz egyébként default értékeket, hogy mindenképpen létezzenek a használt indexek:
1
2
3
4
5
6
7
8
| $array = $array + array(
'select' => '',
'from' => '',
'where' => array(),
'like' => '',
'order' => '',
'limit' => ''
); |
Így csak azt kell nézni, hogy értelmes-e az értékük. Persze még mindig lehet, hogy eleve nem is tömböt adtál át.
Ha használod a "type hinting" -et a paraméterátadásnál ( osztályneveket és az "array" kulcsszót használhatod csak ), akkor át se adhatsz mást, mint tömböt:
1
| public function dbSelect(array $array = array()) { |
Amit pedig te "operand"-nak hívsz, az nem operandus, hanem logikai operátor.
A dbSelect értékében és értelmében nem vagyok biztos. Csak akkor készíts külön metódust valamire, ha az tényleg segíteni fog neked! Amíg a tömbödet feltöltöd, addig az sql-t is megírod. Nem lesz sokkal rövidebb a kódod és hibalehetőség se lesz sokkal kevesebb. A mezőneveket továbbra is elírhatod és nehezebb debugolni is, ha nem látod a készített sql-t. Ezért majd hiba esetén írhatsz print-eket, hogy lásd az sql-t.
Egyféle kapcsolatot tudsz a feltételek között megadni. Vagy AND vagy OR. Nincs lehetőség felváltva vagy zárójelezésre. A speciálisabb összehasonlításokról és függvényekről nem is beszélve.
Csak az inner join-t tudod szimulálni táblák összekapcsolásához több tábla felsorolásával a select-ben. De a táblanevek köré írható "backtick" -et ( `tablaneve` ) kézzel kell úgyis beírnod. Ha nem teszed, egy foglalt szóval gondok lehetnek.
A vagdosós stringes megoldást is át lehetne gondolni, de az nem akkora probléma. Csak a kódolvasást teszi nehezebbé. Pl ha nem rakod bele a where kulcsszót az sql-be előre, akkor hozzátoldhatod, amikor már tudod, hogy lesz feltétel. És nem kell ellenkező esetben visszavágnod a stringet.
Tudom, hogy ez csak kezdeti próbálkozás, de ha ezt egy éles rendszerre írod, akkor inkább próbáld úgy elkészíteni, hogy előbb átgondolod, hogy milyen sql-ekre lesz szükséged. És az azokhoz szükséges általánosítást leprogramozhatod. Nem feltétlenül kell az alap select-ig lemenni. Vagy pedig sokkal profibbat kell írnod, ami viszont már lehet, hogy sokkal több tanulást is igényel. És vannak erre kész megoldások. Csak az alkalmazásuk is sokkal bonyolultabb.
Utoljára szerkesztette: RimElek 2013.05.27. 19:02
|

Kolyok
Kezdő
|
Üdv Mindenkinek.
Nem rég kezdtem el tanulmányozni az OOP PHP-t és próbálkoztam is pár szkript/weblap elkészítésével (kissebb-nagyobb sikerrel).
Mivel a programozást (több nyelven is) teljesen hobby szinten csináltam és csak az érdeklődésemre kiterjedő témákkal foglalkoztam ezért eléggé hiányosnak érzem a tudásom a jelenlegi projektem megvalósításához.
A jelenlegi projektem (vagyis a terve) egy MVC OOP alapon írt tartalom kezelő rendszer lenne (További konkrét infókat nem mondanék mert elég sok minden tervben van de még csak nem rég kezdtem bele).
A rendszer jelenleg zárt forráskódú (inkább úgy mondanám, hogy csak én férek hozzá és szeretném egyedül lerakni az alapjait) viszont az első használható/tesztelhető verzió létrejöttekor természetesen nyílt forráskódú lesz.
Szóval a topik lényege az volna, hogy a segítségeteket/javaslatotokat kérném néhány dologban.
Jelen esetben (ahogy a topik címe is mutatja) a PDO osztály kiterjesztésével kapcsolatban.
Némi keresgélés/olvasás után úgy döntöttem, hogy PDO drivert használok az adatbázis kapcsolatokhoz.
A PDO dokumentációja olvasása során (viszonylag a PDO is új nekem mivel eddig csak MS-SQL adatbázissal dolgoztam sima mssql driverel, nagyon ritkán MySQL adatbázissal is sima mysql driverrel) arra a következtetésre jutottam, hogy a későbbi egyszerűbb használatát/elérhetőségét úgy oldom meg, hogy egy saját osztály kiterjesztést írok hozzá. (egyelőre csak sima SELECT, UPDATE, INSERT statement-ek)
Nos ötleteiteket/javaslataitokat szeretném kérni a lenti kóddal kapcsolatban:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
<?php
class Database extends PDO {
var $dsn = NULL;
var $username = NULL;
var $password = NULL;
var $options = NULL;
var $link = NULL;
public function __construct($dsn, $username, $password, $options) {
try {
$this->link = new PDO($dsn, $username, $password, $options);
} catch (PDOException $e) {
echo 'Hiba: ' . $e->getMessage();
}
}
public function dbSelect($array = array()) {
$query = 'SELECT ' . $array['select'] . ' FROM ' . $array['from'] . ' WHERE ';
if (is_array($array['where']) && $array['where'] != '') {
foreach ($array['where'] as $key => $value) {
if ($array['like']) {
$query .= $key." LIKE :".$key." ".$array['operand'];
} else {
$query .= $key." = :".$key." ".$array['operand']." ";
}
}
$query = substr($query, 0, -(strlen($array['operand']) + 2));
} else {
$query = substr($query, 0, -7);
}
if ($array['order'] != '') {
$query .= ' ORDER BY ' . $array['order'];
}
if ($array['limit'] != '') {
$query .= ' LIMIT ' . $array['limit'];
}
$prepared = $this->link->prepare($query);
$final = array();
if (is_array($array['where']) && $array['where'] != '') {
foreach ($array['where'] as $bind => $to) {
$final[':'.$bind] = $to;
}
}
$prepared->execute($final);
$result = $prepared->fetchAll();
return $result;
}
}
?>
|
A fenti kód eléggé kezdteleges még viszont szeretnék előbb több ötletet/javaslatot ahhoz, hogy mit és hogyan.
Bocsesz a sok szövegért de gondoltam úgy fair ha kicsit kifejtem miről is van szó.
Előre is köszönöm mindenkinek.
|
|