SlideShare a Scribd company logo
Introducing
PHP Data Objects
    Wez Furlong
  wez@omniti.com
The Problem
• No consistency of API between DB
  extensions
• Sometimes no self-consistency within
  a given extension
• Duplicated code (but not)
• High maintenance
The PDO solution
• Move PHP specific stuff into one
  extension
• Database specific stuff (only) in their
  own extensions
• Data access abstraction, not
  database abstraction
Features
• Performance
  – Native C code beats a scripted solution
  – Takes advantage of latest PHP 5 internals
• Power
  – Gives you common DB features as a base
  – Still be able to access specialist functions
• Easy
  – Non-intrusive
  – Clear
• Runtime extensible
  – Drivers can be loaded at runtime
Available Drivers
• Oracle OCI             [PDO_OCI]
• ODBC V3, IBM DB2     [PDO_ODBC]
• MySQL 3.x           [PDO_MYSQL]
• Postgres            [PDO_PGSQL]
• SQLite 3.x         [PDO_SQLITE]
• Firebird         [PDO_FIREBIRD]
Getting PDO [unix]
• Build PHP 5
   --with-zlib --prefix=/usr/local/php5
• pear download PDO-alpha
• tar xzf PDO-*.tgz
• cd PDO-*
• PATH=/usr/local/php5/bin:$PATH
• phpize && ./configure && make
• make install
Getting PDO [unix] 2
• Select the driver(s) you need
• pear download PDO_XXX-alpha
• tar xzf PDO_XXX*.tgz
• cd PDO_XXX*
• phpize && ./configure && make
• make install
Getting PDO [win32]
• Grab the DLLs from the snaps site
 http://snaps.php.net/win32/PECL_5_0/
• You need:
  – php_pdo.dll
  – php_pdo_XXX.dll
• Put them in C:php5ext
Switching it on
• Need to enable PDO in your php.ini
• MUST load PDO first
• Unix:
  extension=pdo.so
  extension=pdo_XXX.so
• Windows
  extension=php_pdo.dll
  extension=php_pdo_XXX.dll
Connecting via PDO
try {
  $dbh = new PDO($dsn,
      $user, $password, $options);
} catch (PDOException $e) {
  echo “Failed to connect:”
               . $e->getMessage();
}
DSN format in PDO
• Driver:optional_driver_specific_stuff
  – sqlite:/path/to/db/file
  – sqlite::memory:
  – mysql:host=name;dbname=dbname
  – pgsql:native_pgsql_connection_string
  – oci:dbname=dbname;charset=charset
  – firebird:dbname=dbname;charset=char
    set;role=role
  – odbc:odbc_dsn
DSN Aliasing
• uri:uri
  – Specify location of a file containing actual DSN
    on the first line
  – Works with streams interface, so remote URLs
    can work too
• name          (with no colon)
  –   Maps to pdo.dsn.name in your php.ini
  –   pdo.dsn.name=sqlite:/path/to/name.db
  –   $dbh = new PDO(„name‟);
  –   $dbh = new PDO(„sqlite:/path/to/name.db‟);
• Neither of these allows for user/pass
  (yet!)
Connection management
try {
  $dbh = new PDO($dsn, $user, $pw);
} catch (PDOException $e) {
  echo “connect failed:” . $e->getMessage();
}
// use the database here
// …

// done; release the connection
$dbh = null;
Persistent PDO
$dbh = new PDO($dsn, $user, $pass,
   array(
     PDO_ATTR_PERSISTENT => true
   )
);
• Can specify a string instead of true
  – Useful for keeping 2 connections open
    with similar credentials
Persistent PDO 2
• PDO_ODBC supports native
  connection pooling by default
• Likely to be more resource efficient
  than PDO „pconnect‟
• Can turn it off in php.ini:
  pdo_odbc.connection_pooling=off
• Need to restart web server after
  changing it
Let’s get data
$dbh = new PDO($dsn);
$stmt = $dbh->prepare(
               „SELECT * FROM FOO‟);
$stmt->execute();
while ($row = $stmt->fetch()) {
   print_r($row);
}
Fetch types
• $stmt->fetch(PDO_FETCH_BOTH)
  – Array with numeric and string keys
  – default option
• PDO_FETCH_NUM
  – Array with numeric keys
• PDO_FETCH_ASSOC
  – Array with string keys
• PDO_FETCH_OBJ
  – $obj->name holds the „name‟ column from the row
• PDO_FETCH_BOUND
  – Just returns true until there are no more rows
Let’s change data
$deleted = $dbh->query(
      “DELETE FROM FOO WHERE 1”);

$changes = $dbh->query(
   “UPDATE FOO SET active=1 ”
 . “WHERE NAME LIKE „%joe%‟”);
Smarter Queries
• Quoting is annoying, but essential
• PDO offers a better way
$stmt->prepare(„INSERT INTO CREDITS
  (extension, name) VALUES (:extension,
  :name)‟);
$stmt->execute(array(
  „:extension‟ => „xdebug‟,
  „:name‟ => „Derick Rethans‟
));
Binding for output
$stmt = $dbh->prepare(
          "SELECT extension, name from CREDITS");
if ($stmt->execute()) {
   $stmt->bindColumn(„extension', $extension);
   $stmt->bindColumn(„name',       $name);
   while ($stmt->fetch(PDO_FETCH_BOUND)) {
     echo “Extension: $extensionn”;
     echo “Author: $namen”;
   }
}
Portability Aids
• PDO aims to make it easier to write
  db independent apps
• Number of hacks^Wtweaks for this
  purpose

$dbh->setAttribute(
               PDO_ATTR_ORACLE_NULLS, true);
• Converts empty strings to NULL when fetched
PDO_ATTR_CASE
• Some databases (notably, Oracle) insist on returning
  column names in uppercase

$dbh->setAttribute(PDO_ATTR_CASE, PDO_CASE_UPPER);
$stmt = $dbh->prepare(
         "SELECT extension, name from CREDITS");
if ($stmt->execute()) {
   $stmt->bindColumn(„EXTENSION', $extension);
   $stmt->bindColumn(„NAME',       $name);
   while ($stmt->fetch(PDO_FETCH_BOUND)) {
     echo “Extension: $extensionn”;
     echo “Author: $namen”;
   }
}
Data typing
• Very loose
• uses strings for data
• Gives you more control over data
  conversion
Error handling
• PDO offers 3 different error modes
$dbh->setAttribute(PDO_ATTR_ERRMODE, $mode);
  – PDO_ERRMODE_SILENT
  – PDO_ERRMODE_WARNING
  – PDO_ERRMODE_EXCEPTION
• Attempts to map native codes to
  PDO generic codes
• But still offers native info too
PDO_ERRMODE_SILENT
if (!$dbh->query($sql)) {
   echo $dbh->errorCode() . "<br>";
   $info = $dbh->errorInfo();
   // $info[0] == $dbh->errorCode()
   //    unified error code
   // $info[1] is the driver specific
   //    error code
   // $info[2] is the driver specific
   //    error string
}
PDO_ERRMODE_EXCEPTION
try {
  $dbh->exec($sql);
} catch (PDOException $e) {
  // display warning message print
  $e->getMessage();
  $info = $e->errorInfo;
  // $info[0] == $e->code;
  //    unified error code
  // $info[1] is the driver specific error code
  // $info[2] is the driver specific error string
}
Transactions
try {
  $dbh->beginTransaction();
  $dbh->query(„UPDATE …‟);
  $dbh->query(„UPDATE …‟);
  $dbh->commit();
} catch (PDOException $e) {
  $dbh->rollBack();
}
Cool stuff on the horizon
• Iterators (coming real soon)
  foreach ($stmt->execute() as $row)
• LOB support via streams
  – Bind the parameter
  – fwrite, fread(), fseek() on the LOB
• Scrollable cursors
Resources
• Oracle Technology Network article
 http://www.oracle.com/technology/pub/articles/php_expert
 s/otn_pdo_oracle5.html

• These slides and other PDO news
  bytes
  http://netevil.org
• Bugs?
  http://pecl.php.net/bugs/report.php?
  package=PDO_XXX

More Related Content

What's hot (20)

PDF
Moodle 3.3 - API Change Overview #mootieuk17
Dan Poltawski
 
PDF
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
 
PDF
Dependency Injection with PHP 5.3
Fabien Potencier
 
PDF
PHP 5.3 Overview
jsmith92
 
PDF
Unit and Functional Testing with Symfony2
Fabien Potencier
 
PDF
4069180 Caching Performance Lessons From Facebook
guoqing75
 
KEY
CodeIgniter 3.0
Phil Sturgeon
 
PDF
Php unit the-mostunknownparts
Bastian Feder
 
PDF
Dependency injection in PHP 5.3/5.4
Fabien Potencier
 
PDF
Crud operations using aws dynamo db with flask ap is and boto3
Katy Slemon
 
PDF
Symfony2 - WebExpo 2010
Fabien Potencier
 
PDF
Alfredo-PUMEX
tutorialsruby
 
PDF
SPL: The Missing Link in Development
jsmith92
 
PDF
Facebook的缓存系统
yiditushe
 
PDF
PHP 良好實踐 (Best Practice)
Win Yu
 
PPTX
Webinar: Replication and Replica Sets
MongoDB
 
PDF
Doctrine MongoDB ODM (PDXPHP)
Kris Wallsmith
 
PDF
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Fabien Potencier
 
PPTX
Php functions
JIGAR MAKHIJA
 
PDF
Advanced symfony Techniques
Kris Wallsmith
 
Moodle 3.3 - API Change Overview #mootieuk17
Dan Poltawski
 
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
 
Dependency Injection with PHP 5.3
Fabien Potencier
 
PHP 5.3 Overview
jsmith92
 
Unit and Functional Testing with Symfony2
Fabien Potencier
 
4069180 Caching Performance Lessons From Facebook
guoqing75
 
CodeIgniter 3.0
Phil Sturgeon
 
Php unit the-mostunknownparts
Bastian Feder
 
Dependency injection in PHP 5.3/5.4
Fabien Potencier
 
Crud operations using aws dynamo db with flask ap is and boto3
Katy Slemon
 
Symfony2 - WebExpo 2010
Fabien Potencier
 
Alfredo-PUMEX
tutorialsruby
 
SPL: The Missing Link in Development
jsmith92
 
Facebook的缓存系统
yiditushe
 
PHP 良好實踐 (Best Practice)
Win Yu
 
Webinar: Replication and Replica Sets
MongoDB
 
Doctrine MongoDB ODM (PDXPHP)
Kris Wallsmith
 
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Fabien Potencier
 
Php functions
JIGAR MAKHIJA
 
Advanced symfony Techniques
Kris Wallsmith
 

Similar to Introducing PHP Data Objects (20)

PPT
Quebec pdo
Valentine Dianov
 
PDF
Quebec pdo
Rengga Aditya
 
PDF
PHP Data Objects
Wez Furlong
 
PDF
Service discovery and configuration provisioning
Source Ministry
 
ODP
PHP Data Objects
Prashant Marathe
 
PDF
Pecl Picks
Elizabeth Smith
 
KEY
Scaling php applications with redis
jimbojsb
 
PDF
Drupal 7 database api
Andrii Podanenko
 
PDF
Living With Legacy Code
Rowan Merewood
 
KEY
Fatc
Wade Arnold
 
ODP
Zend Framework 1.9 Setup & Using Zend_Tool
Gordon Forsythe
 
PDF
Xdebug - Derick Rethans - Barcelona PHP Conference 2008
phpbarcelona
 
PPTX
Power shell training
David Brabant
 
PDF
Building Testable PHP Applications
chartjes
 
ODP
CodeIgniter PHP MVC Framework
Bo-Yi Wu
 
PDF
Andriy Podanenko.Drupal database api.DrupalCamp Kyiv 2011
camp_drupal_ua
 
PDF
Getting started with TDD - Confoo 2014
Eric Hogue
 
PDF
Building Custom PHP Extensions
AzRy LLC, Caucasus School of Technology
 
PDF
Lean Php Presentation
Alan Pinstein
 
Quebec pdo
Valentine Dianov
 
Quebec pdo
Rengga Aditya
 
PHP Data Objects
Wez Furlong
 
Service discovery and configuration provisioning
Source Ministry
 
PHP Data Objects
Prashant Marathe
 
Pecl Picks
Elizabeth Smith
 
Scaling php applications with redis
jimbojsb
 
Drupal 7 database api
Andrii Podanenko
 
Living With Legacy Code
Rowan Merewood
 
Zend Framework 1.9 Setup & Using Zend_Tool
Gordon Forsythe
 
Xdebug - Derick Rethans - Barcelona PHP Conference 2008
phpbarcelona
 
Power shell training
David Brabant
 
Building Testable PHP Applications
chartjes
 
CodeIgniter PHP MVC Framework
Bo-Yi Wu
 
Andriy Podanenko.Drupal database api.DrupalCamp Kyiv 2011
camp_drupal_ua
 
Getting started with TDD - Confoo 2014
Eric Hogue
 
Building Custom PHP Extensions
AzRy LLC, Caucasus School of Technology
 
Lean Php Presentation
Alan Pinstein
 
Ad

More from webhostingguy (20)

PPT
File Upload
webhostingguy
 
PDF
Running and Developing Tests with the Apache::Test Framework
webhostingguy
 
PDF
MySQL and memcached Guide
webhostingguy
 
PPT
Novell® iChain® 2.3
webhostingguy
 
PDF
Load-balancing web servers Load-balancing web servers
webhostingguy
 
PDF
SQL Server 2008 Consolidation
webhostingguy
 
PDF
What is mod_perl?
webhostingguy
 
PDF
What is mod_perl?
webhostingguy
 
PDF
Master Service Agreement
webhostingguy
 
PPT
Notes8
webhostingguy
 
PPT
PHP and MySQL PHP Written as a set of CGI binaries in C in ...
webhostingguy
 
PDF
Dell Reference Architecture Guide Deploying Microsoft® SQL ...
webhostingguy
 
PPT
Managing Diverse IT Infrastructure
webhostingguy
 
PPT
Web design for business.ppt
webhostingguy
 
PPS
IT Power Management Strategy
webhostingguy
 
PPS
Excel and SQL Quick Tricks for Merchandisers
webhostingguy
 
PPT
OLUG_xen.ppt
webhostingguy
 
PPT
Parallels Hosting Products
webhostingguy
 
PPT
Microsoft PowerPoint presentation 2.175 Mb
webhostingguy
 
PDF
Reseller's Guide
webhostingguy
 
File Upload
webhostingguy
 
Running and Developing Tests with the Apache::Test Framework
webhostingguy
 
MySQL and memcached Guide
webhostingguy
 
Novell® iChain® 2.3
webhostingguy
 
Load-balancing web servers Load-balancing web servers
webhostingguy
 
SQL Server 2008 Consolidation
webhostingguy
 
What is mod_perl?
webhostingguy
 
What is mod_perl?
webhostingguy
 
Master Service Agreement
webhostingguy
 
PHP and MySQL PHP Written as a set of CGI binaries in C in ...
webhostingguy
 
Dell Reference Architecture Guide Deploying Microsoft® SQL ...
webhostingguy
 
Managing Diverse IT Infrastructure
webhostingguy
 
Web design for business.ppt
webhostingguy
 
IT Power Management Strategy
webhostingguy
 
Excel and SQL Quick Tricks for Merchandisers
webhostingguy
 
OLUG_xen.ppt
webhostingguy
 
Parallels Hosting Products
webhostingguy
 
Microsoft PowerPoint presentation 2.175 Mb
webhostingguy
 
Reseller's Guide
webhostingguy
 
Ad

Introducing PHP Data Objects

  • 2. The Problem • No consistency of API between DB extensions • Sometimes no self-consistency within a given extension • Duplicated code (but not) • High maintenance
  • 3. The PDO solution • Move PHP specific stuff into one extension • Database specific stuff (only) in their own extensions • Data access abstraction, not database abstraction
  • 4. Features • Performance – Native C code beats a scripted solution – Takes advantage of latest PHP 5 internals • Power – Gives you common DB features as a base – Still be able to access specialist functions • Easy – Non-intrusive – Clear • Runtime extensible – Drivers can be loaded at runtime
  • 5. Available Drivers • Oracle OCI [PDO_OCI] • ODBC V3, IBM DB2 [PDO_ODBC] • MySQL 3.x [PDO_MYSQL] • Postgres [PDO_PGSQL] • SQLite 3.x [PDO_SQLITE] • Firebird [PDO_FIREBIRD]
  • 6. Getting PDO [unix] • Build PHP 5 --with-zlib --prefix=/usr/local/php5 • pear download PDO-alpha • tar xzf PDO-*.tgz • cd PDO-* • PATH=/usr/local/php5/bin:$PATH • phpize && ./configure && make • make install
  • 7. Getting PDO [unix] 2 • Select the driver(s) you need • pear download PDO_XXX-alpha • tar xzf PDO_XXX*.tgz • cd PDO_XXX* • phpize && ./configure && make • make install
  • 8. Getting PDO [win32] • Grab the DLLs from the snaps site http://snaps.php.net/win32/PECL_5_0/ • You need: – php_pdo.dll – php_pdo_XXX.dll • Put them in C:php5ext
  • 9. Switching it on • Need to enable PDO in your php.ini • MUST load PDO first • Unix: extension=pdo.so extension=pdo_XXX.so • Windows extension=php_pdo.dll extension=php_pdo_XXX.dll
  • 10. Connecting via PDO try { $dbh = new PDO($dsn, $user, $password, $options); } catch (PDOException $e) { echo “Failed to connect:” . $e->getMessage(); }
  • 11. DSN format in PDO • Driver:optional_driver_specific_stuff – sqlite:/path/to/db/file – sqlite::memory: – mysql:host=name;dbname=dbname – pgsql:native_pgsql_connection_string – oci:dbname=dbname;charset=charset – firebird:dbname=dbname;charset=char set;role=role – odbc:odbc_dsn
  • 12. DSN Aliasing • uri:uri – Specify location of a file containing actual DSN on the first line – Works with streams interface, so remote URLs can work too • name (with no colon) – Maps to pdo.dsn.name in your php.ini – pdo.dsn.name=sqlite:/path/to/name.db – $dbh = new PDO(„name‟); – $dbh = new PDO(„sqlite:/path/to/name.db‟); • Neither of these allows for user/pass (yet!)
  • 13. Connection management try { $dbh = new PDO($dsn, $user, $pw); } catch (PDOException $e) { echo “connect failed:” . $e->getMessage(); } // use the database here // … // done; release the connection $dbh = null;
  • 14. Persistent PDO $dbh = new PDO($dsn, $user, $pass, array( PDO_ATTR_PERSISTENT => true ) ); • Can specify a string instead of true – Useful for keeping 2 connections open with similar credentials
  • 15. Persistent PDO 2 • PDO_ODBC supports native connection pooling by default • Likely to be more resource efficient than PDO „pconnect‟ • Can turn it off in php.ini: pdo_odbc.connection_pooling=off • Need to restart web server after changing it
  • 16. Let’s get data $dbh = new PDO($dsn); $stmt = $dbh->prepare( „SELECT * FROM FOO‟); $stmt->execute(); while ($row = $stmt->fetch()) { print_r($row); }
  • 17. Fetch types • $stmt->fetch(PDO_FETCH_BOTH) – Array with numeric and string keys – default option • PDO_FETCH_NUM – Array with numeric keys • PDO_FETCH_ASSOC – Array with string keys • PDO_FETCH_OBJ – $obj->name holds the „name‟ column from the row • PDO_FETCH_BOUND – Just returns true until there are no more rows
  • 18. Let’s change data $deleted = $dbh->query( “DELETE FROM FOO WHERE 1”); $changes = $dbh->query( “UPDATE FOO SET active=1 ” . “WHERE NAME LIKE „%joe%‟”);
  • 19. Smarter Queries • Quoting is annoying, but essential • PDO offers a better way $stmt->prepare(„INSERT INTO CREDITS (extension, name) VALUES (:extension, :name)‟); $stmt->execute(array( „:extension‟ => „xdebug‟, „:name‟ => „Derick Rethans‟ ));
  • 20. Binding for output $stmt = $dbh->prepare( "SELECT extension, name from CREDITS"); if ($stmt->execute()) { $stmt->bindColumn(„extension', $extension); $stmt->bindColumn(„name', $name); while ($stmt->fetch(PDO_FETCH_BOUND)) { echo “Extension: $extensionn”; echo “Author: $namen”; } }
  • 21. Portability Aids • PDO aims to make it easier to write db independent apps • Number of hacks^Wtweaks for this purpose $dbh->setAttribute( PDO_ATTR_ORACLE_NULLS, true); • Converts empty strings to NULL when fetched
  • 22. PDO_ATTR_CASE • Some databases (notably, Oracle) insist on returning column names in uppercase $dbh->setAttribute(PDO_ATTR_CASE, PDO_CASE_UPPER); $stmt = $dbh->prepare( "SELECT extension, name from CREDITS"); if ($stmt->execute()) { $stmt->bindColumn(„EXTENSION', $extension); $stmt->bindColumn(„NAME', $name); while ($stmt->fetch(PDO_FETCH_BOUND)) { echo “Extension: $extensionn”; echo “Author: $namen”; } }
  • 23. Data typing • Very loose • uses strings for data • Gives you more control over data conversion
  • 24. Error handling • PDO offers 3 different error modes $dbh->setAttribute(PDO_ATTR_ERRMODE, $mode); – PDO_ERRMODE_SILENT – PDO_ERRMODE_WARNING – PDO_ERRMODE_EXCEPTION • Attempts to map native codes to PDO generic codes • But still offers native info too
  • 25. PDO_ERRMODE_SILENT if (!$dbh->query($sql)) { echo $dbh->errorCode() . "<br>"; $info = $dbh->errorInfo(); // $info[0] == $dbh->errorCode() // unified error code // $info[1] is the driver specific // error code // $info[2] is the driver specific // error string }
  • 26. PDO_ERRMODE_EXCEPTION try { $dbh->exec($sql); } catch (PDOException $e) { // display warning message print $e->getMessage(); $info = $e->errorInfo; // $info[0] == $e->code; // unified error code // $info[1] is the driver specific error code // $info[2] is the driver specific error string }
  • 27. Transactions try { $dbh->beginTransaction(); $dbh->query(„UPDATE …‟); $dbh->query(„UPDATE …‟); $dbh->commit(); } catch (PDOException $e) { $dbh->rollBack(); }
  • 28. Cool stuff on the horizon • Iterators (coming real soon) foreach ($stmt->execute() as $row) • LOB support via streams – Bind the parameter – fwrite, fread(), fseek() on the LOB • Scrollable cursors
  • 29. Resources • Oracle Technology Network article http://www.oracle.com/technology/pub/articles/php_expert s/otn_pdo_oracle5.html • These slides and other PDO news bytes http://netevil.org • Bugs? http://pecl.php.net/bugs/report.php? package=PDO_XXX