PDO är något som man när man leker med php kommer över lite då och då på diverse forum. Mycket tycker jag det finns bra guider som är lätta hitta, men PDO känner jag har hamnat lite på efterkälken.
Vad är då PDO? PDO är väl ett klassbibliotek som fungerar som ett databas-gränssnitt tror jag man skulle kunna förklara det.
Jag tänkte förklara lite genom kod.
vi börjar med att skapa oss en databas och en tabell. Gör detta genom något bekvämt gränssnitt t.ex. phpmyadmin. (lägg sedan till några poster)
CREATE DATABASE `pdoskola` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
USE `pdoskola`;
CREATE TABLE IF NOT EXISTS `employees` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fname` varchar(50) NOT NULL,
`lname` varchar(50) NOT NULL,
`position` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Här skapar vi en databas som heter pdoskola där vi sedan skapar en tabell som heter employees som har 4 kolumner. En index-kolumn som heter id som är ett heltal, en som heter fname, en lname och sist en position som alla är varchars (sträng).
Om vi med dom vanliga metoderna i php skulle t.ex. hämta en post ifrån denna (som förvisso nu är tom men ändå) så skulle det se ut ungefär såhär:
<?php
$conn = mysql_connect(‘localhost’,'root’,”);
$db = ‘pdoskola’;
mysql_select_db($db,$conn);
$sql = "select * from employees";
$result = mysql_query($sql,$conn);
$rows = mysql_fetch_assoc($result);
do{
print_r($rows);
} while ($rows = mysql_fetch_assoc($result));
mysql_close($conn);
?>
Ingen ovanlig syn.
Motsvarande i PDO hade sett ut såhär:
<?php
$dbh = new PDO(‘mysql:host=localhost;dbname=pdoskola’,'root’,”);
$result = $dbh->query(‘select * from employees’);
foreach($result as $row) {
print_r($row);
}
$dbh = null;
?>
Wow tänker du. Men det är inte här som PDO kommer till sin sanna rätt. Men det återkommer vi till senare så ska jag förklara kodraderna ovan först.
$dbh = new PDO(‘mysql:host=localhost;dbname=pdoskola’,'root’,”);
Vad vi gör här är att vi skapar en ny instans av klassen PDO. Klassen PDO behöver våra parametrar för att ansluta till databasen för att kunna skapas. Första parametern anger vad det är för typ av databas. I detta fall en mysql, men det skulle kunna vara sqllite: eller kanske odbc:. Detta följs sedan av host som man matar med server-addressen och dbname som helt enkelt är databas-namnet, sista två är användarnamn och lösenord.
Vad vi sedan gör är att vi använder den instansierade $dbh (jag väljer dbh för DataBaseHandler) för att köra en query mot databasen och matar ut resultatet i en $result.
$result i sig blir en instansiering av PDO vilket gör att man kan köra $result->rowCount(); (returnerar en integer) för att få antal rader som hämtades eller t.ex. $result->errorInfo(); (returnerar en array) om något gått snett.
Men det är när man börjar med att försöka ställa frågor mot databasen baserade på parametervärden t.ex. som man börjar märka skillnader.
Om vi skulle försöka söka i vår databas efter förnamnet osc (jag har i min databas lagt in en anställd som heter Oscar hade man fått göra ungefär såhär för att göra det på det gamla vanliga sättet:
<?php
echo "<h2>PHP-MYSQL</h2>";
$_POST['fname'] = ‘osc’;
$conn = mysql_connect(‘localhost’,'root’,”);
$db = ‘pdoskola’;
mysql_select_db($db,$conn);
if(get_magic_quotes_gpc())
$_POST['fname'] = stripslashes($_POST['fname']);
$_POST['fname'] = mysql_real_escape_string($_POST['fname'],$conn);
$sql = "select * from employees where fname like ‘%".$_POST['fname']."%’";
$result = mysql_query($sql,$conn) or die (mysql_error());
$rows = mysql_fetch_assoc($result);
do{
print_r($rows);
} while ($rows = mysql_fetch_assoc($result));
mysql_close($conn);
?>
Vi får börja med att tvätta vårat indata. Detta gör man minst med stripslashes och sedan med mysql_real_escape_string. Då är man hyfsat på det torra iallafall.
Sedan kör man in detta i en query där man kollar med hjälp av like om det finns något förnamn som passar.
Nu ska vi se vad vi hittar på med hjälp av PDO, där kommer några överraskningar.
<?php
echo "<h2>PDO</h2>";
$_POST['fname'] = ‘Osc’;
$dbh = new PDO(‘mysql:host=localhost;dbname=pdoskola’,'root’,”);
$statement = $dbh->prepare(‘select * from employees where fname like concat("%",:fname,"%")’);
$statement->bindValue(‘:fname’,$_POST['fname']);
$statement->execute();
$result = $statement->fetchAll();
foreach($result as $row) {
print_r($row);
}
$_POST['fname'] = ‘Olof’;
$statement->bindValue(‘:fname’,$_POST['fname']);
$statement->execute();
$result = $statement->fetchAll();
foreach($result as $row) {
print_r($row);
}
$dbh = null;
?>
Vi märker direkt att jag aldrig tvättar datat någonstans. Det sköter PDO själv så det är bara att köra på. Vad som däremot kommer till är $dbh->prepare där ni ser att jag skrivit in min query fast med :fname i. Detta är en förberedelse till att köra en query med en parameter som heter :fname. På nästa rad binder jag :fname till $_POST[‘fname’] följt av en execute som kör queryn mot databasen. Det fina i detta ser vi några rader längre ned. Eftersom jag har gjort ett PDOstatement som visar hur queryn ska se ut så kan jag helt enkelt bara binda om :fname och köra execute igen med det nya värdet på :fname. Hur fiffigt är inte det? Tar både hand om skadlig kod och fungerar bra för återanvändning!
Man behöver inte binda värden till parametrar man kan använda ? istället för :fname och sedan köra $statement->execute(array(‘Osc’)); lika gärna. Men i min värld tappar man struktur och snyggt kodande jämför med att köra bindvalue. Med bindvalue kan man dessutom styra vilken typ av variabel som ska vara där ($statement->bindValue(‘:fname’,$_POST['fname'],PDO::PARAM_STR); t.ex.) Något som också gäller parametrarna är att man behöver inte bry sig om ‘ eller “ med strängar eller tal då PDO sköter detta och ordnar. PDO förstår också att $_POST[‘fname’] aldrig kommer ha värdet osc’;delete from employees where 1=1 t.ex.
Något annat som är riktigt coolt är att PDO stödjer att hämta poster in i objekt. Ska visa här nedan.
<?php
class Colleague {
public $fname;
public $lname;
public $position;
public function getColleagueInfo() {
return $this->fname.’ ‘.$this->lname.’ ‘.$this->position;
}
}
$dbh = new PDO("mysql:host=localhost;dbname=pdoskola", ‘root’, ”);
$statement = $dbh->prepare("SELECT * FROM employees");
$statement->setFetchMode(PDO::FETCH_INTO, new Colleague);
$statement->execute();
foreach($statement as $collie)
echo $collie->getColleagueInfo().’<br />’;
$dbh = null;
?>
Vilket i sin tur innebär att man kan jobba väldigt lätt med sina objekt. Men visst, det är inte så mycket extra jobb att instansiera ett objekt och sätta några värden med vanlig mysql_query heller. Men det är inte lika snyggt 
Nu har jag visat lite grunder och när du kommer igång och testar och ser olika klasser så kommer det vara lättare att komma vidare förhoppningsvis.
Senaste kommentarer