extends MySQL
Ik vraag me af wat de beste manier is om
een MySQL class te gebruiken.
Vaak extend ik een class met een MySQL class waarbij meerdere tellers en MySQL functies in zitten.
Graag zou ik willen weten of het wel de goede manier is om
MySQl te gebruiken.
En hoe dat zit met de stack en de heap.
voorbeeld:
Alvast bedankt.
Gewijzigd op 07/01/2015 22:58:01 door Unthinking majority
het is alleen niet de bedoeling om bijvoorbeeld een user class te laten extenden op mysql
als je in de user class een database connectie nodig hebt:
Allemaal bedankt voor de snelle reacties.
Dan denk ik MySQLi toch per class apart te gaan gebruiken.
Dat zal met het sluiten van MySQL ook beter gaan.
Wat ik nu nog heb is:
Code (php)
Ik begrijp nu dat dit niet de bedoeling is.
Mijn MySQL class wat ik nu nog heb ziet er ongeveer zo uit:
Code (php)
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
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
<?php
class MySQL{
private $row;
private $result;
private $mysqli;
protected $teller;
protected $array;
public function __destruct() {$this->mysqli->close();}
protected function run($query){
include ("verbindmysqlinclass.php");
$sql =
<<<SQL
$query
SQL;
$this->result = $this->mysqli->query($sql);
if (!$this->result){
die("Er is iets fout gegaan bij het uitvoeren van de query ". $this->mysqli->error);
}
else{ if (is_object($this->result)){
$this->teller = $this->result->num_rows;
}
else{
$this->teller = 0;
}
}
}
protected function escapestringetje($naampje){
include ("verbindmysqlinclass.php");
$naampje = $this->mysqli->real_escape_string($naampje);
return $naampje;
}
protected function geef($array){
$hoeveelheid = count($array); //tel de inhoud van de array
for($i = 0; $i < $hoeveelheid; $i++) { //for loopje
$this->{"$array[$i]"} = array(); //maak een variabele aan die de naam heeft van de inkomende array
//van die variabele wordt ook meteen een array gemaakt.
}
while ($this->row = $this->result->fetch_array()) { //het resultaat van de query array wordt in $this->row gezet {
//$this-row wordt dus doorlooped totdat die helemaal gevult is tot het einde
for($i = 0; $i < $hoeveelheid; $i++) { // een for loopje
array_push($this->{"$array[$i]"}, $this->row[$i]); // hier wordt de inkomende naam tegelijkertijd gevuld met de waardes van de mysql row
}
}
$this->result->free();
}
}
?>
class MySQL{
private $row;
private $result;
private $mysqli;
protected $teller;
protected $array;
public function __destruct() {$this->mysqli->close();}
protected function run($query){
include ("verbindmysqlinclass.php");
$sql =
<<<SQL
$query
SQL;
$this->result = $this->mysqli->query($sql);
if (!$this->result){
die("Er is iets fout gegaan bij het uitvoeren van de query ". $this->mysqli->error);
}
else{ if (is_object($this->result)){
$this->teller = $this->result->num_rows;
}
else{
$this->teller = 0;
}
}
}
protected function escapestringetje($naampje){
include ("verbindmysqlinclass.php");
$naampje = $this->mysqli->real_escape_string($naampje);
return $naampje;
}
protected function geef($array){
$hoeveelheid = count($array); //tel de inhoud van de array
for($i = 0; $i < $hoeveelheid; $i++) { //for loopje
$this->{"$array[$i]"} = array(); //maak een variabele aan die de naam heeft van de inkomende array
//van die variabele wordt ook meteen een array gemaakt.
}
while ($this->row = $this->result->fetch_array()) { //het resultaat van de query array wordt in $this->row gezet {
//$this-row wordt dus doorlooped totdat die helemaal gevult is tot het einde
for($i = 0; $i < $hoeveelheid; $i++) { // een for loopje
array_push($this->{"$array[$i]"}, $this->row[$i]); // hier wordt de inkomende naam tegelijkertijd gevuld met de waardes van de mysql row
}
}
$this->result->free();
}
}
?>
Maar ik begrijp nu ook dat het mogelijk is om MySQLi rechstreeks te extenden.
Gewijzigd op 08/01/2015 12:55:28 door unthinking majority
Gewijzigd op 08/01/2015 15:46:49 door Frank Nietbelangrijk
Iedereen erg bedankt voor de mogelijkheden.
Ivo P op 08/01/2015 09:34:56:
een database class, die dus iets doet met databases, kan inderdaad mysql(i) extenden.
het is alleen niet de bedoeling om bijvoorbeeld een user class te laten extenden op mysql
als je in de user class een database connectie nodig hebt:
het is alleen niet de bedoeling om bijvoorbeeld een user class te laten extenden op mysql
als je in de user class een database connectie nodig hebt:
Probeer dit in gedachte te houden.
Want ik zie nu dat je dit eigenlijk niet doet.
Het kan wel, maar een extend is een uitbreiding op.
Heeft een profiel een relatie met een database?
Het antwoord is nee. Want je hebt alleen een database nodig om gegevens van een profiel te laden dus extenden op een database is niet nodig.
In jou geval zou het dus iets moeten worden als:
Code (php)
In je class MySQL kan je wel extenden. Want daar is een connectie met mysqli wel nodig dus is wel een uitbreiding op.
Quote:
Dat zal met het sluiten van MySQL ook beter gaan.
Je weet dat het niet perse nodig is om de database connectie te sluiten?
Dit gebeurt automagisch aan het einde van het script.
Mits dat je gebruik maakt van een persistent connection.. Dan heb je dat probleem.
De reactie daarna is een beetje misleidend want dat was wat ik toen nog had en nog niet met verbeteringen.
PDO lijkt mij ook een goede manier.
Wegens de MySQL hackers in de media en overbelasting lijkt mij het wel beter om de database connecties te sluiten terwijl het voor de werking niet nodig is.
Een profiel heeft inderdaad niet direct een relatie met MySQL en daar ga ik mijn script op verbeteren.
Bedankt voor de extra uitleg met voorbeelden.
Dit zijn ongegronde argumenten, en bovendien is het slecht voor je performance om telkens verbindingen te openen en sluiten. Gewoon niet sluiten. Dat regelt PHP allemaal zelf.
Wat en hoe heb je gemeten?
Welk stuk is traag?
Indien dat allemaal (nog) niet van toepassing is is er geen probleem. :)
Het is het zelfde als de denkwijze waarin je je script gaat verbeteren.
Als de verbinding niet nodig is, dan gebruik je het ook niet.
Een ander argument is om dit php zelf te laten regelen is dat als je je per ongeluk de verbinding te vroeg sluit je applicatie om zeep is. En dat kan uuuuuuuuuuuuren debuggen worden waarom het niet werkt.
Gewijzigd op 09/01/2015 16:33:10 door Bart V B
http://us.php.net/manual/en/mysqli.close.php
Quote:
Open connections (and similar resources) are automatically destroyed at the end of script execution. However, you should still close or free all connections, result sets and statement handles as soon as they are no longer required. This will help return resources to PHP and MySQL faster.
Daarom dacht ik dat het sluiten beter was.
Over de MySQL hacken dacht ik meer aan de media en het lijkt mij dat je er alleen binnen kan komen als het deurtje open staat of als die te makkelijk open te duwen is.
Ik begrijp niet welk script hiermee bedoeld wordt.
PHP of de MySQL query.
Toevoeging op 09/01/2015 19:06:05:
Het stuk op devzone.zend.com heb ik gevonden.
http://devzone.zend.com/239/ext-mysqli-part-i_overview-and-prepared-statements/
Er staat dat er verschil zit tussen de oude en de nieuwe versie.
Dat is niet wat de manual voor schrijft.
De manual zegt alleen dat het een vorige connectie sluit meer niet.
Hoewel de meeste user comments goede tips bevatten is deze van 6 jaar geleden.
Het kan natuurlijk zijn dat de user een berg connecties naar de database maakt waardoor het allemaal erg traag werd, en ja dan is het logisch dat je de close functie gebruikt om de VORIGE connectie te sluiten.
Het openen en sluiten van een database connectie heeft iets van doen met veiligheid.
Je kan zowel met een verkeerd php script, dan wel met een verkeerde (onveilige) query je site hackbaar maken. Ik kan legio aan voorbeelden schrijven hoe het onveilig zou kunnen worden, maar dat doe ik niet. :)
Beter is om je tips te geven om het veilig te maken.
Dwing in je php code af wat verwacht word.
Dus als jij een invoerveld hebt wat verwacht dat alleen nummers bevat dan moet je daarop controleren.
Een string een minimale en maximale lengte geven bijvoorbeeld.
Verwacht je geen tags in je invoer verwijder ze, of controleer er op en geef een foutmelding.
PHP heeft tegenwoordig een filter_var() functie, dat maakt het leven al een stuk aangenamer.
(http://php.net/manual/en/function.filter-var.php)
Als alles klopt wat je verwacht, dan zet je het pas in de database.
Zowel PDO als mysqli hebben de prepared statement functies aan boord.
Die zorgen er voor dat je inhoud correct een veilig in de database komen.
En dan moet het op server nivo ook allemaal nog goed geregeld zijn, maar dat is voor dit topic ietsje te veel van het goede. ;)
EDIT
Ik zie net dat je hebt zitten editen in je post..
Dat artikel is van March 16, 2004.. Dat is van toen ik nog haar op mijn hoofd had.
Dus als jij met een versie werkt die uit die tijd stamt dan word het tijd om eens wat te updaten. Dat is allemaal niet meer relevant.
Overigens is het wel zo dat mysql_connect niet meer werkt in de nieuwste versie, daarom word hier vaak het advies gegeven om over te stappen naar mysqli of PDO.
PDO is leuk als je bijvoorbeeld een zou willen overstappen naar een andere database.
Bijvoorbbeeld SQLite, of postgres.
Gewijzigd op 09/01/2015 19:40:19 door Bart V B
Ik wel er wel even iets aan toevoegen.
Prepared statements worden op de een af andere manier heilig beschouwd in de PHP wereld.
Dat zijn ze niet en in veel gevallen volkomen overbodig. Het is namelijk zo dat zowel MySQli als PDO eerst een querie naar de db-server stuurt, die wordt geëvalueerd en er wordt een query plan aan gehangen. Dan krijgt de client een pointer naar terug waarna met behulp van die pointer de query telkens uitgevoerd met de verschillende parameters.
Bij eenmalige query's kan je het binden van die parameters net zo goed oplossen met een escape of type casting.
Gewijzigd op 09/01/2015 20:29:04 door Ger van Steenderen
Quote:
Ik zie net dat je hebt zitten editen in je post..
Het was een toevoeging of aanvulling op het bericht.
Voor de veiligheid doe ik alles in combinatie met regular expressions.
Mijn laptop is laatst stuk gegaan en ik gebruik nu versie: 5.6.21
Ik ga proberen over te stappen op PDO maar ben daar nog over aan het lezen.
Wat ik me afvraag bij PDO is of daar ook een real_escape_string in zit en of dat nog nodig is.
De prepared statements zitten er inderdaad wel in maar ik vraag me af of dit een goede vervanger is van de real_escape_string.
Toevoeging op 09/01/2015 20:35:17:
En het antwoord zat in het bericht hiervoor die ik nog niet gelezen had.
Bedankt voor de tips.
Dat is een hele goede toevoeging. Want type casting en of escape is natuurlijk ook heel goed mogelijk.
De uitleg heb ik mijzelf eigenlijk nooit in verdiept hoe het prepared statement ding eigenlijk zijn werk doet. Dus ben eigenlijk wel heel blij dat je het even opmerkt hoe dat ding eigenlijk onder water werkt.
Dank daarvoor.
Quote:
Mijn laptop is laatst stuk gegaan en ik gebruik nu versie: 5.6.21
Bedoel je php of mysql?
Quote:
Voor de veiligheid doe ik alles in combinatie met regular expressions.
Poeh.. jij liever dan ik :)
Iets met een allergie voor regular expressions..
Quote:
De prepared statements zitten er inderdaad wel in maar ik vraag me af of dit een goede vervanger is van de real_escape_string.
PDO heeft ook een escape_string optie hoor. :)
http://php.net/manual/en/pdo.quote.php
Via http://www.regex101.com
Kun je regular expressies testen wat het 1000 x makkelijker maakt vind ik persoonlijk.
Handig dat de escape string er ook in zit. Bedankt.
Code (php)
De klasse zelf opent hier een databaseverbinding en plaats van een elders geopende database te hergebruiken. Gevolg daarvan kan een bekend performance-probleem veroorzaken: 45 queries uitvoeren via 45 databaseverbindingen voor één enkele webpagina.
In dat geval kán het vroegtijdig sluiten van de verbindingen helpen, al is een ander OOP-ontwerp maken natuurlijk beter.
het is overzichtelijker als je $this->db = db::getDbVerbinding(); oid gebruikt.
Maar als je via php meerdere connecties met dezelfde inloggegevens gebruikt, wordt de bestaande verbinding opnieuw gebruikt en krijg je dus niet 10 exact dezelfde verbindingen.
Wel is het een beetje eng, wat hierboven gedaan wordt: bij het destructen van een object wordt de verbinding gesloten.
Maar het zou een beetje jammer zijn als het destructen van een object zou zorgen dat alle andere objecten ineens geen db-verbinding meer hebben.
Bedankt voor de waarschuwing en uitleg.
Wat ik nu van plan ben om te doen is ongeveer dit:
Code (php)
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
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
<?php
include_once "Statisch.class.php";
class Profiel{
private $host;
private $database;
private $username;
private $password;
public function __construct(){
$this->host = Statisch::getHost();
$this->database = Statisch::getDb();
$this->username = Statisch::getUser();
$this->password = Statisch::getDb();
try
{
$this->db = new PDO("mysql:host=". $this->host .";dbname=". $this->database ."",$this->username, $this->password);
}
catch(PDOException $e)
{
echo '<pre>';
echo 'Regelnummer: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage().'<br>';
echo '</pre>';
}
}
}
$object = new Profiel();
?>
include_once "Statisch.class.php";
class Profiel{
private $host;
private $database;
private $username;
private $password;
public function __construct(){
$this->host = Statisch::getHost();
$this->database = Statisch::getDb();
$this->username = Statisch::getUser();
$this->password = Statisch::getDb();
try
{
$this->db = new PDO("mysql:host=". $this->host .";dbname=". $this->database ."",$this->username, $this->password);
}
catch(PDOException $e)
{
echo '<pre>';
echo 'Regelnummer: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage().'<br>';
echo '</pre>';
}
}
}
$object = new Profiel();
?>
Quote:
Maar het zou een beetje jammer zijn als het destructen van een object zou zorgen dat alle andere objecten ineens geen db-verbinding meer hebben.
Daarbij vraag ik me af hoe dat zit tussen de stack en de heap.
Wat ik tussen stack en heap begrijp is dat het bij $object pas in de heap terecht komt.
Maar ik begrijp dan nog niet of dan ook alles in de heap komt inclusief de include_once "Statisch.class.php";
of als er een object extends wordt met een andere class en of die dan ook meteen in de heap terecht komt.
Gewijzigd op 11/01/2015 19:31:54 door unthinking majority