Apachecon Advanced Oo Database Access Using Pdo
Apachecon Advanced Oo Database Access Using Pdo
Marcus Brger
ApacheCon EU 2005
Intro
PHP and Databases PHP 5 and PDO
Marcus Brger
Marcus Brger
Dedicated Host
Apache Internet Browser Browser
Browser Browser Browser Browser Browser
mod_php
Marcus Brger
ISP/Shared Host
Apache Internet Browser Browser
Browser Browser Browser Browser Browser
mod_php
Marcus Brger
Embedded
GTK / ???
CLI / EMBED
dba / dbase
NO SQL
Marcus Brger
Embedded
GTK / ???
Marcus Brger
All talk some SQL dialect and All using different API
Marcus Brger
Marcus Brger
10
PDO at a glance
Data access abstraction (API unification) Multiple database plug-in extensions Object oriented Iterator support Destructive read support All written in a tiny c layer Will be used us base layer of upcoming MDB2 Available through PECL
Buildable for PHP 5.0 Built-in starting from 5.1 Windows DLLs available Already used in a few production servers ATM still marked experimental
Marcus Brger Advanced Object Oriented Database access using PDO 11
PDO at a glance
Prepared statements (unified, name and index) SQL state error code Portability attributes Transaction supprt Scrollable cursors Uses normal PHP error facilities or Exceptions Plans: LOB support
Marcus Brger
12
Marcus Brger
13
Marcus Brger
14
Marcus Brger
15
Marcus Brger
16
Marcus Brger
17
Marcus Brger
19
Marcus Brger
20
Marcus Brger
21
associative array numeric array default (assoc/numeric) into stdClass object into bound variables single column into new instance into existing object through function call group by first col group unique by first col use class name in row use serialization
22
PDO_FETCH_BOUND
Fetching returns true until there is no more data
Binding parameters by "?" in sql (1 based index) Binding parameters by ":name" in sql Binding columns by name and index
$dbh = new PDO($dsn); $stmt = $dbh->prepare( 'SELECT url FROM urls WHERE key=:urlkey'); $stmt->bindParam(':urlkey', $urlkey); $stmt->bindColumn('url', $href); $urlkey = ...; // get url key to translate $stmt->execute(); // execute the query // fetch data $stmt->fetch(PDO_FETCH_BOUND); // use data echo '<a href="' . $href . '">' . $urlkey . '</a>';
Marcus Brger Advanced Object Oriented Database access using PDO 23
PDO_FETCH_BOUND
Fetching returns true until there is no more data
Binding Binding Binding Binding parameters by "?" in sql 1 based index parameters by ":name" in sql columns by name and index can be done on execute()
$dbh = new PDO($dsn); $stmt = $dbh->prepare( 'SELECT url FROM urls WHERE key=:urlkey'); $urlkey = ...; // get url key to translate $stmt->execute(array(':urlkey' => $urlkey), array('url' => $href)); // fetch data $stmt->fetch(PDO_FETCH_BOUND); // use data echo '<a href="' . $href . '">' . $urlkey . '</a>';
Marcus Brger Advanced Object Oriented Database access using PDO 24
PDO_FETCH_CLASS
Lets you specify the class to instantiate
PDO_FETCH_OBJ always uses stdClass Writes data before calling __construct
Can write private/protected members
PDO_FETCH_CLASSTYPE
Lets you fetch the class to instantiate from rows
Must be used with PDO_FETCH_CLASS The class name specified in fetch mode is a fallback
class Person { /* ... */ } class Employee extends Person { /* ... */ } class Manager extends Employee { /* ... */ } $stmt = $dbh->prepare( 'SELECT class, fname, lname FROM persons LEFT JOIN classes ON persons.kind = classes.id'); $stmt->setFetchMode(PDO_FETCH_CLASS|PDO_FETCH_CLASSTYPE, 'Person', array($dbh)); $stmt->execute(); foreach($stmt as $person) { echo $person; }
Marcus Brger
26
PDO_FETCH_INTO
Lets you reuse an already instantiated object Does not allow to read into protected or private
Because the constructor was already executed
class Person { public $dbh, $fname, $lname; function __construct($dbh) { $this->dbh = $dbh; } function __toString() { return $this->fname . " " . $this->lname; } } $stmt = $dbh->prepare('SELECT fname, lname FROM persons'); $stmt->setFetchMode(PDO_FETCH_INTO, new Person($dbh)); $stmt->execute(); foreach($stmt as $person) { echo $person; }
Marcus Brger Advanced Object Oriented Database access using PDO 27
PDO_FETCH_FUNC
Lets you specify a function to execute on each row
class Person { protected $fname, $lname; static function Factory($fname, $lname) { $obj = new Person; $obj->fname = $fname; $obj->lname = $lname; } function __toString() { return $this->fname . " " . $this->lname; } } $stmt = $dbh->prepare('SELECT fname, lname FROM persons'); $stmt->setFetchMode(PDO_FETCH_FUNC, array('Person', 'Factory')); $stmt->execute(); foreach($stmt as $person) { echo $person; }
Marcus Brger Advanced Object Oriented Database access using PDO 28
Marcus Brger
29
Deriving PDOStatement
prepare() allows to specify fetch attributes
PDOStatement PDO::prepare( string $sql, array(PDO_ATTR_STATEMENT_CLASS => array(string classname, array(mixed * ctor_args)))); class MyPDOStatement extends PDOStatement { protected $dbh; function __construct($dbh) { $this->dbh = $dbh; } } $dbh->prepare($sql, array(PDO_ATTR_STATEMENT_CLASS => array('MyPDOStatement', array($dbh))));
Marcus Brger
30
Deriving PDOStatement
Deriving allows to convert to real iterator
class PDOStatementAggregate extends PDOStatement implements IteratorAggregate { private function __construct($dbh, $classtype) { $this->dbh = $dbh; $this->setFetchMode(PDO_FETCH_CLASS, $classtype, array($this)); } function getIterator() { $this->execute(); return new IteratorIterator($this, 'PDOStatement'); /* Need to be base class */ } } $stmt = $dbh->prepare('SELECT * FROM Persons', array(PDO_ATTR_STATEMENT_CLASS => array('PDOStatementAggregate', array($dbh, 'Person')))); foreach($stmt as $person){ echo $person; }
Marcus Brger Advanced Object Oriented Database access using PDO 31
Map native codes to SQLSTATE standard codes Aditionally offers native info
Marcus Brger
32
Performance
10 times Querying 10 rows Iterators vs. Arrays
Implemented as engine feature: 56% Building an Array is expensive
Marcus Brger
33
Performance
Buffered vs. Unbuffered: up to 60%
Buffered queries need to build a hash table Buffered queries must copy data Unbuffered queries can use destructive reads Copying data is expensive
Marcus Brger
34
Performance
Comparing OO vs. Procedural code
PC is easy to program? PC uses resources: PC uses a single function table: OO code is little bit more to learn OO code is easy to maintain OO code uses object storage: OO uses small method tables:
O(n*log(n))
2000 ... 4000
O(n+c)
10 ... 100
Marcus Brger
35
Performance?
Don't get overexcited using PDO your RDBMS is your bottlneck
Marcus Brger
36
Links
This presenatation http://talks.somabo.de Documenation on PDO http://docs.php.net/pdo The PDO Extension http://pecl.php.net/package/PDO The Windows DLLs http://snaps.php.net
Marcus Brger
37