[MySQL] Wel of niet overgaan op MySQLi?
Ik zit met een klein probleem. Ik hoorde dat het beter is om over te gaan op de MySQLi functie. Dit wil ik dan uiteraard ook doen.
Mijn probleem is dus nu: ik heb een bestaande website, met meer dan 200 SQL queries. Is het 't waard om deze allemaal te converteren naar MySQLi? En wat zijn de voor- en nadelen?
Zo ja, hoe kan ik een SQL query het beste converteren?
Bij voorbaad dank,
Kevin Ruhl.
Het betreft alleen de functies van mysql, dus de queries op zich blijven het zelfde.
Wanneer je moet overgaan in mijn ogen is:
- Wanneer je begint aan nieuwe code
- Wanneer je je website een grote update geeft en wil dat deze over een aantal jaar nog steeds werkt. (Het zal nog wel even duren voor de functie daadwerkelijk niet meer werkt)
Je zou er dus voor kiezen, wanneer je dingen gaat wijzigen gelijk die code te wijzigen in mysqli.
Hier heb je een lijstje met de verschillen in Mysql en Mysqli
De mysql_* functies praten achter de schermen op een iets verouderde manier met je MySQL database.
mysql_* functies worden niet meer bijgewerkt, en zijn deprecated (gemarkeert om ergens in de toekomst verwijderd te worden)
De makkelijkste (maar iets wat lelijke manier):
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
$GLOBALS['mysqli'] = mysqli_connect(...);
mysqli_query($GLOBALS['mysqli'], "SQL");
mysqli_real_escape_string($GLOBALS['mysqli'], $_POST['iets']);
?>
$GLOBALS['mysqli'] = mysqli_connect(...);
mysqli_query($GLOBALS['mysqli'], "SQL");
mysqli_real_escape_string($GLOBALS['mysqli'], $_POST['iets']);
?>
Zodra je dat werkend hebt kun je nog heel wat van je source gaan herschrijven zodat je de OO interface gebruikt EN via Dependency Injection werkt zodat je niet met $GLOBALS hoeft te kloten.
Kevin Ruhl op 14/04/2014 09:12:42:
Mijn probleem is dus nu: ik heb een bestaande website, met meer dan 200 SQL queries. Is het 't waard om deze allemaal te converteren naar MySQLi? En wat zijn de voor- en nadelen?
Elke doorgewinterde programmeur zou bij deze vraag een ander vraagteken zetten.... Of je 2, 200, of 20.000 queries hebt, een aanpassing als overgaan van mysql naar mysqli zou je maar op 1 plek hoeven te maken. Als jij hierboven eigenlijk zegt dat je die 200 queries ook op 200 plekken in je code afwerkt, dan sta je nu ook voor de keuze of je dat niet zou moeten aanpassen...
In de praktijk is het vaak gewoon een 'í' toevoegen aan de functie: mysql_query() -> mysqli_query(). Let dan wel op dat sommige functies een extra argument nodig hebben met daarin een verwijzing naar de connectie, waaronder mysqli_query() en mysqli_real_escape_string():
Op php.net/[functienaam] (bijv. http://php.net/mysqli_query) staat het allemaal uitlegd in de 'syntax'.
- Aar - op 14/04/2014 09:21:57:
Gezien alles bij de MySQL-database blijft hoeven de queries gelukkig niet veranderd te worden, maar alleen de functies die je gebruikt. Met een simpele en logisch 'search and replace' is alles in no-time wel voorelkaar te krijgen.
In de praktijk is het vaak gewoon een 'í' toevoegen aan de functie: mysql_query() -> mysqli_query(). Let dan wel op dat sommige functies een extra argument nodig hebben met daarin een verwijzing naar de connectie, waaronder mysqli_query() en mysqli_real_escape_string():
Op php.net/[functienaam] (bijv. http://php.net/mysqli_query) staat het allemaal uitlegd in de 'syntax'.
In de praktijk is het vaak gewoon een 'í' toevoegen aan de functie: mysql_query() -> mysqli_query(). Let dan wel op dat sommige functies een extra argument nodig hebben met daarin een verwijzing naar de connectie, waaronder mysqli_query() en mysqli_real_escape_string():
Op php.net/[functienaam] (bijv. http://php.net/mysqli_query) staat het allemaal uitlegd in de 'syntax'.
De reden dat ik $GLOBALS['mysqli'] gebruikte in plaats van $mysqli is vanwege de volgende feature van de mysql_* functies: "If the link identifier is not specified, the last link opened by mysql_connect() is assumed."
Dat betekend dat je in een functie prima mysql_query() aan kunt roepen zonder een link (vaak opgeslagen in $link of $mysqli) aan die functie door te geven.
Voor de mysqli_* functies is dat niet zo...
Voorbeeld search & replace code: http://3v4l.org/0WiJ5
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
$old = <<<'NOWDOC'
[code]<?php
// Connect
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(mysql_error());
// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
?>
NOWDOC;
$new = preg_replace('/mysql_([a-zA-Z_]+)\(/', 'mysqli_$1($GLOBALS[\'link\'], ', $old);
$new = str_replace('mysqli_connect($GLOBALS[\'link\'], ', 'mysqli_connect(', $new);
$new = str_replace(', )', ')', $new);
echo $new;
?>
$old = <<<'NOWDOC'
[code]<?php
// Connect
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(mysql_error());
// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
?>
NOWDOC;
$new = preg_replace('/mysql_([a-zA-Z_]+)\(/', 'mysqli_$1($GLOBALS[\'link\'], ', $old);
$new = str_replace('mysqli_connect($GLOBALS[\'link\'], ', 'mysqli_connect(', $new);
$new = str_replace(', )', ')', $new);
echo $new;
?>
Zodra je het werkend en geupload hebt kun je het daarna op een elegantere manier oplossen.
Dan bedoel ik dus ZONDER $GLOBALS!
Gewijzigd op 14/04/2014 10:13:05 door Dos Moonen
Ik heb besloten om het toch te doen, qua werk valt het mee met wat ik in de eerste instantie dacht.
Dos Moonen op 14/04/2014 10:11:22:
- Aar - op 14/04/2014 09:21:57:
Zodra je het werkend en geupload hebt kun je het daarna op een elegantere manier oplossen.
Dan bedoel ik dus ZONDER $GLOBALS!
Dan bedoel ik dus ZONDER $GLOBALS!
Hiermee bedoel je zeker iets als global $connect; zoals ik deze hieronder heb gebruikt?
Config.php:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
$host = 'localhost';
$name = 'naam';
$pass = 'pass';
$db = 'database';
$connect = mysqli_connect($host, $name, $pass, $db);
$name = 'naam';
$pass = 'pass';
$db = 'database';
$connect = mysqli_connect($host, $name, $pass, $db);
Functions.php:
Code (php)
1
2
3
4
2
3
4
function test() {
global $connect;
mysqli_query($connect,"SELECT * FROM tabel ORDER BY id DESC");
}
global $connect;
mysqli_query($connect,"SELECT * FROM tabel ORDER BY id DESC");
}
Gewijzigd op 14/04/2014 12:43:55 door Kevin Ruhl
$GLOBAL is van nature al global.
Dus dat maakt zeker met zoek-en-vervang je werk een stukje eenvoudiger.
Nog handiger is het misschien om 1 file te hebben waarin alle query's uitgevoerd worden (+ afhandeling fouten) en eventueel ook + van resultset-naar-array acties.
Dan staat alles in 1 file, en was de overgang nog eenvoudiger.
Ivo P op 14/04/2014 12:48:08:
nadeel van $connect is, dat je dan in elke functie waarin mogelijk een query staat, je die regel "global $connect" moet zetten.
$GLOBAL is van nature al global.
Dus dat maakt zeker met zoek-en-vervang je werk een stukje eenvoudiger.
Nog handiger is het misschien om 1 file te hebben waarin alle query's uitgevoerd worden (+ afhandeling fouten) en eventueel ook + van resultset-naar-array acties.
Dan staat alles in 1 file, en was de overgang nog eenvoudiger.
$GLOBAL is van nature al global.
Dus dat maakt zeker met zoek-en-vervang je werk een stukje eenvoudiger.
Nog handiger is het misschien om 1 file te hebben waarin alle query's uitgevoerd worden (+ afhandeling fouten) en eventueel ook + van resultset-naar-array acties.
Dan staat alles in 1 file, en was de overgang nog eenvoudiger.
True that, maar opzich is het geen verkeerde manier om het zo aan te pakken?
Misschien zou ik wel zo'n file system kunnen maken, maar ik moet dit eerst even zo werkend krijgen, dat het er permanent mee door zou kunnen gaan.
Op zich is dat een verkeerde manier om het aan te pakken.
Maar daarna zeg je dat je eerst een lelijke manier met superieure functies werkend wilt hebben met de intentie om het daarna op te schonen.
Dan vind ik het acceptabel.
Maar zonder een plan voor de toekomst is het dus een verkeerde manier om het zo aan te pakken.
Config.php
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
function query($sql) {
return mysqli_query(mysqli_connect('localhost', 'naam', 'pass', 'database'),$sql);
}
function real_escape_string($sql) {
return mysqli_real_escape_string(mysqli_connect('localhost', 'naam', 'pass', 'database'),$sql);
}
return mysqli_query(mysqli_connect('localhost', 'naam', 'pass', 'database'),$sql);
}
function real_escape_string($sql) {
return mysqli_real_escape_string(mysqli_connect('localhost', 'naam', 'pass', 'database'),$sql);
}
Functions.php:
Gewijzigd op 14/04/2014 13:52:43 door Kevin Ruhl
De snelle actie zou zijn om in die file eenmalig een $connect te vullen en die in deze ene file steeds global er bij te halen.
Mooier is een PDO oplossing, of een zelf geschreven variant waarbij je $this->connectie gebruikt
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
function query($sql) {
return mysqli_query(mysqli_connect('localhost', 'naam', 'pass', 'database'),$sql);
}
function real_escape_string($sql) {
return mysqli_real_escape_string(mysqli_connect('localhost', 'naam', 'pass', 'database'),$sql);
}
return mysqli_query(mysqli_connect('localhost', 'naam', 'pass', 'database'),$sql);
}
function real_escape_string($sql) {
return mysqli_real_escape_string(mysqli_connect('localhost', 'naam', 'pass', 'database'),$sql);
}
Is nog lelijker en moeilijker te onderhouden dan global $link; of $GLOBALS['link'] gebruiken.