PDO en database
Pagina: « vorige 1 2 3 volgende »
Ozzie PHP op 07/10/2011 18:48:16:
Ik dacht dat PDO bedoeld was om makkelijk tussen databases te kunnen switchen, maar als ik het zo allemaal eens lees is het dus eigenlijk alleen maar de connection waar het om gaat.
Er staat ook nergens geschreven dat het makkelijk is.
Tuutlijk kun je met PDO makkelijk switchen tussen dbenhines maar (lees mijn eerdere berichten)
Ger, zoals ik zei ik dacht dat PDO een abstractielaag was. Je stuurt PDO als het ware aan, en PDO doet de rest ongeacht welke database er aan is gekoppeld. Het heeft er niet mee te maken of het makkelijk of moeilijk is. Het gaat er om welk voordeel je hebt door PDO te gebruiken.
Gewijzigd op 07/10/2011 21:23:32 door Ger van Steenderen
Ja, maar dat is volgens velen hier op het forum volgens mij toch echt niet het geval... er wordt altijd gezegd dat PDO de beste keuze is. Vreemd?????
Ik gebruik zelf MySQLi_ op het moment "Ik gebruik alleen maar MySQL databases tot nu toe".
Gewijzigd op 07/10/2011 22:49:44 door - Mark -
Tja, dus de vraag is... waarom is PDO zo geweldig, zoals door velen hier op het forum wordt beweerd. Gaat het alleen om het feit dat je met meerdere database types kunt connecten? Of zijn er nog andere voordelen?
prepared statements...
- Aar - op 07/10/2011 23:53:41:
prepared statements...
in plaats van mysql_real_escape_string? Is dat dan het enige echte voordeel?
Ozzie PHP op 07/10/2011 18:48:16:
Ik dacht dat PDO bedoeld was om makkelijk tussen databases te kunnen switchen, maar als ik het zo allemaal eens lees is het dus eigenlijk alleen maar de connection waar het om gaat.
Dat is het ook, maar je moet wel generieke SQL schrijven. En dat is een grote beperking, geen enkele database zal daarmee écht lekker kunnen werken.
Tip: Wanneer je SQL wilt schrijven volgens de ANSI-standaarden, ga dan bouwen en testen met PostgreSQL. Deze houdt zich zeer goed aan de standaarden en dit werkt meestal ook direct in o.a. SQLite, MySQL, Oracle, Firebird en zelfs SQL Server.
Wanneer je MySQL gaat gebruiken om te ontwikkelen, vergeet PDO dan maar, de MySQL-smaak van SQL gaat echt niet werken op andere databases. MySQL gebruikt hele rare constructies en geeft ook onmogelijke antwoorden op foute queries. Een query die dan "werkt" op MySQL (levert gewoon een fout antwoord op die toevallig goed lijkt te zijn), zal nergens anders werken omdat de query gewoon fout is.
php.net:
While PDO has its advantages, such as a clean, simple, portable API, its main disadvantage is that it doesn't allow you to use all of the advanced features that are available in the latest versions of MySQL server. For example, PDO does not allow you to use MySQL's support for Multiple Statements.
I rest my case
Gewijzigd op 08/10/2011 10:31:38 door Ger van Steenderen
Ozzie PHP op 08/10/2011 00:02:02:
in plaats van mysql_real_escape_string? Is dat dan het enige echte voordeel?
- Aar - op 07/10/2011 23:53:41:
prepared statements...
in plaats van mysql_real_escape_string? Is dat dan het enige echte voordeel?
Dan begrijp je niet wat prepared statements zijn. I.p.v. real_escape_string heeft PDO namelijk de functie pdo.quote.
Bij prepared statements maak je eerst een lege query aan, die wordt gecontroleerd en in de cache van de database gestopt. Vervolgens kun je deze query veel sneller aanroepen en veel vaker. Voorbeeldje:
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
try
{
$pdo = new PDO('mysql:host=localhost;dbname=mijnDB', 'user', 'pass');
$pQuery = "SELECT name, pass FROM mijnTabel WHERE id = :id";
$stmt = $pdo->prepare($pQuery);
$users = Array(1,2,6); // Select users with id 1, 2 and 6
foreach( $users as $user )
{
$stmt->bindParam(':id', $user, PDO::PARAM_INT);
$stmt->execute();
while( $row = $stmt->fetch(PDO::FETCH_ASSOC) )
{
echo 'Username: '.$row['name']."<br>\nPass: ".$row['pass']."<br>\n";
}
}
}
catch( PDOException $e )
{
error_log(date('d-m-Y::H:i').' '.$e->getFile().'('.$e->getLine().') '.$e->getMessage());
}
?>
try
{
$pdo = new PDO('mysql:host=localhost;dbname=mijnDB', 'user', 'pass');
$pQuery = "SELECT name, pass FROM mijnTabel WHERE id = :id";
$stmt = $pdo->prepare($pQuery);
$users = Array(1,2,6); // Select users with id 1, 2 and 6
foreach( $users as $user )
{
$stmt->bindParam(':id', $user, PDO::PARAM_INT);
$stmt->execute();
while( $row = $stmt->fetch(PDO::FETCH_ASSOC) )
{
echo 'Username: '.$row['name']."<br>\nPass: ".$row['pass']."<br>\n";
}
}
}
catch( PDOException $e )
{
error_log(date('d-m-Y::H:i').' '.$e->getFile().'('.$e->getLine().') '.$e->getMessage());
}
?>
Je hebt helemaal gelijk, maar je hoeft niet in elke loop een nieuwe bindParam aan te maken. Dit doe je buiten je loop, waarbij de referentie naar de variabele behouden blijft. Overigens vind ik het niet heel logisch om een loop te gebruiken voor een select query. Je kan dan beter veld IN (2,5,6) gebruiken, maar dit terzijde. Het is voornamelijk interessant bij INSERT en UPDATE queries.
Dus dit werkt ook en is volgens mij de juiste methode:
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
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
<?php
try
{
$pdo = new PDO('mysql:host=localhost;dbname=mijnDB', 'user', 'pass');
$pQuery = "SELECT name, pass FROM mijnTabel WHERE id = :id";
$stmt = $pdo->prepare($pQuery);
$stmt->bindParam(':id', $user_id, PDO::PARAM_INT);
$users = Array(1,2,6); // Select users with id 1, 2 and 6
foreach( $users as $user )
{
$user_id = $user;
$stmt->execute();
while( $row = $stmt->fetch(PDO::FETCH_ASSOC) )
{
echo 'Username: '.$row['name']."<br>\nPass: ".$row['pass']."<br>\n";
}
}
}
catch( PDOException $e )
{
error_log(date('d-m-Y::H:i').' '.$e->getFile().'('.$e->getLine().') '.$e->getMessage());
}
?>
try
{
$pdo = new PDO('mysql:host=localhost;dbname=mijnDB', 'user', 'pass');
$pQuery = "SELECT name, pass FROM mijnTabel WHERE id = :id";
$stmt = $pdo->prepare($pQuery);
$stmt->bindParam(':id', $user_id, PDO::PARAM_INT);
$users = Array(1,2,6); // Select users with id 1, 2 and 6
foreach( $users as $user )
{
$user_id = $user;
$stmt->execute();
while( $row = $stmt->fetch(PDO::FETCH_ASSOC) )
{
echo 'Username: '.$row['name']."<br>\nPass: ".$row['pass']."<br>\n";
}
}
}
catch( PDOException $e )
{
error_log(date('d-m-Y::H:i').' '.$e->getFile().'('.$e->getLine().') '.$e->getMessage());
}
?>
Gewijzigd op 08/10/2011 12:00:01 door Arjan -
in mysqli heb je ook prepared statements
Hmmm, ik ga me er tzt wel wat beter in verdiepen. Ik begreep echt van andere leden op het forum dat je het beste PDO kunt gebruiken, omdat PDO kan praten met verschillende typen databases. Nú begrijp ik echter dat het met name om het connecten gaat. Met andere woorden ik heb een website die gebruik maakt van een MySQL database (via PDO). Nu wil iemand (om wat voor reden dan ook) een andere database type gaan gebruiken voor die website. Het idee was nu dat je alleen de PDO connection hoeft te wijzigen en dat alles dan nog steeds werkt. Maar blijkbaar is dit dus niet het geval omdat de SQL syntax kan verschillen, waardoor het niet meer werkt. Tja, die meerwaarde van PDO vind ik dan ook maar een beetje overdreven.
Ozzie PHP op 08/10/2011 13:52:06:
Hmmm, ik ga me er tzt wel wat beter in verdiepen. Ik begreep echt van andere leden op het forum dat je het beste PDO kunt gebruiken, omdat PDO kan praten met verschillende typen databases.
Dat klopt.
Quote:
Nú begrijp ik echter dat het met name om het connecten gaat.
Dat klopt gedeeltelijk, PDO doet meer dan dat, het zorgt voor één manier om met verschillende databases te kunnen communiceren. Het is wrapper/API om de verschillende connectors voor de verschillende databases.
Quote:
Met andere woorden ik heb een website die gebruik maakt van een MySQL database (via PDO). Nu wil iemand (om wat voor reden dan ook) een andere database type gaan gebruiken voor die website. Het idee was nu dat je alleen de PDO connection hoeft te wijzigen en dat alles dan nog steeds werkt.
Dat klopt, dat is heel goed mogelijk. Je moet hier alleen wel rekening mee houden. En dus ga je testen op de databases die jij wilt gaan ondersteunen.
Quote:
Maar blijkbaar is dit dus niet het geval omdat de SQL syntax kan verschillen, waardoor het niet meer werkt.
Fout, 99 van de 100 queries werken prima via PDO op de verschillende databases zonder dat je ook maar iets hoeft aan te passen. Even een andere connectie opzetten en klaar ben je:
SELECT * FROM test;
INSERT INTO test(id, var) VALUES(1, 'content');
UPDATE test SET var = 'andere content' WHERE id = 1;
DELETE FROM test WHERE id = 1;
Wanneer je specifieke SQL gaat schrijven voor één specifieke database en je gaat dit ook niet testen op andere databases, tja, dan weet je vooraf dat het niet gaat werken. Dat is echt jouw eigen keuze. Bovenstaande voorbeelden van SQL werken op vrijwel alle databases die SQL spreken en dit is al snel 95% van alle SQL die in alle bekende applicaties wordt uitgevoerd. Dit is echt niks bijzonders. Zelfs MySQL kun je zo configureren dat deze normale SQL accepteert en zich beter aan de standaarden houdt.
Quote:
Tja, die meerwaarde van PDO vind ik dan ook maar een beetje overdreven.
Je hebt er nog nauwelijks mee gewerkt, hoe kun je hier dan een mening over hebben? PDO is niet perfect, maar probeer eens iets te bedenken hier op aarde wat wel perfect is?
Ik :+)
Dankjewel Bart... als het klopt wat jij zegt dat PDO in de meeste gevallen wel werkt en dat je alleen de connection hoeft te veranderen... dan is het natuurlijk geweldig! Alleen uit de voorgaande berichten begreep ik dat dat niet het geval is.
Als je PDO gebruikt kan je de functies die bijvoorbeeld je result-set fetchen en omzetten in iets waar je wat mee kan hergebruiken voor verschillende databases, omdat PDO de interface naar de database abstraheert. Of je nu met Oracle of MySQL praat, PDOStatement::fetch() werkt hetzelfde. Zou je de MySQLi gebruiken, dan zou je ook je functie moeten aanpassen.
Oké.. maar kun je dan concluderend stellen dat de meeste dingen wel werken voor de meeste databases, maar in enkele gevallen werkt het niet vanwege een afwijkende syntax?
Ozzie PHP op 09/10/2011 21:51:27:
Oké.. maar kun je dan concluderend stellen dat de meeste dingen wel werken voor de meeste databases, maar in enkele gevallen werkt het niet vanwege een afwijkende syntax?
Het kan mis gaan met de SQL, verschillende databases kunnen verschillende dialecten gebruiken. Daarnaast doet MySQL nog wel eens hele rare dingen, bv. het optellen van appels en peren wat wiskundig niet eens kan:
Volgens MySQL is komt hier "2" uit...
Ga dus niet ontwikkelen met MySQL wanneer je ook andere databases wilt ondersteunen, dit soort rare constructies werkt echt op geen enkele database. Behalve MySQL...
Met standaard SQL en een database die zich goed aan de standaarden houdt, bv. PostgreSQL of Firebird, ga je weinig problemen tegenkomen. Uiteraard ga je geen database-specifieke functies gebruiken, die zijn niet aanwezig in andere databases. Gebruik dus generieke datatypes, queries, functies en operators, dan gaat het als een zonnetje.