29
Introducing PHP Data Objects Wez Furlong [email protected]

Introducing PHP Data Objects

Embed Size (px)

Citation preview

Page 1: Introducing PHP Data Objects

IntroducingPHP Data Objects

Wez [email protected]

Page 2: Introducing PHP Data Objects

The Problem

• No consistency of API between DB extensions

• Sometimes no self-consistency within a given extension

• Duplicated code (but not)• High maintenance

Page 3: Introducing PHP Data Objects

The PDO solution

• Move PHP specific stuff into one extension

• Database specific stuff (only) in their own extensions

• Data access abstraction, not database abstraction

Page 4: Introducing PHP Data Objects

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

Page 5: Introducing PHP Data Objects

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]

Page 6: Introducing PHP Data Objects

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

Page 7: Introducing PHP Data Objects

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

Page 8: Introducing PHP Data Objects

Getting PDO [win32]

• Grab the DLLs from the snaps sitehttp://snaps.php.net/win32/PECL_5_0/

• You need:– php_pdo.dll– php_pdo_XXX.dll

• Put them in C:\php5\ext

Page 9: Introducing PHP Data Objects

Switching it on

• Need to enable PDO in your php.ini• MUST load PDO first • Unix:

extension=pdo.soextension=pdo_XXX.so

• Windowsextension=php_pdo.dllextension=php_pdo_XXX.dll

Page 10: Introducing PHP Data Objects

Connecting via PDO

try { $dbh = new PDO($dsn, $user, $password, $options);} catch (PDOException $e) { echo “Failed to connect:” . $e->getMessage();}

Page 11: Introducing PHP Data Objects

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=charset;role=role

– odbc:odbc_dsn

Page 12: Introducing PHP Data Objects

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!)

Page 13: Introducing PHP Data Objects

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;

Page 14: Introducing PHP Data Objects

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

Page 15: Introducing PHP Data Objects

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

Page 16: Introducing PHP Data Objects

Let’s get data

$dbh = new PDO($dsn);$stmt = $dbh->prepare( ‘SELECT * FROM FOO’);$stmt->execute();while ($row = $stmt->fetch()) { print_r($row);}

Page 17: Introducing PHP Data Objects

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

Page 18: Introducing PHP Data Objects

Let’s change data

$deleted = $dbh->query( “DELETE FROM FOO WHERE 1”);

$changes = $dbh->query( “UPDATE FOO SET active=1 ” . “WHERE NAME LIKE ‘%joe%’”);

Page 19: Introducing PHP Data Objects

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’));

Page 20: Introducing PHP Data Objects

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: $extension\n”; echo “Author: $name\n”; }}

Page 21: Introducing PHP Data Objects

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

Page 22: Introducing PHP Data Objects

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: $extension\n”; echo “Author: $name\n”; }}

Page 23: Introducing PHP Data Objects

Data typing

• Very loose• uses strings for data• Gives you more control over data

conversion

Page 24: Introducing PHP Data Objects

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

Page 25: Introducing PHP Data Objects

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}

Page 26: Introducing PHP Data Objects

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}

Page 27: Introducing PHP Data Objects

Transactions

try { $dbh->beginTransaction(); $dbh->query(‘UPDATE …’); $dbh->query(‘UPDATE …’); $dbh->commit();} catch (PDOException $e) { $dbh->rollBack();}

Page 28: Introducing PHP Data Objects

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

Page 29: Introducing PHP Data Objects

Resources

• Oracle Technology Network articlehttp://www.oracle.com/technology/pub/articles/php_experts/otn_pdo_oracle5.html

• These slides and other PDO news byteshttp://netevil.org

• Bugs?http://pecl.php.net/bugs/report.php?package=PDO_XXX