PHP Data Objects
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

PHP Data Objects

on

  • 36,831 views

PHP Data Objects (PDO) provides a clear, simple (but powerful), unified API for working with all our favorite databases. Features include prepared statements with bound parameters (for all databases, ...

PHP Data Objects (PDO) provides a clear, simple (but powerful), unified API for working with all our favorite databases. Features include prepared statements with bound parameters (for all databases, even those that don’t natively support them), transactions, cursors, LOBs, and flexible error handling.

Statistics

Views

Total Views
36,831
Views on SlideShare
35,575
Embed Views
1,256

Actions

Likes
33
Downloads
955
Comments
2

31 Embeds 1,256

http://netevil.org 475
http://cachi.temiga.org 210
http://wezfurlong.org 202
http://www.slideshare.net 124
http://www.blogdopedro.net 87
http://www.planet-php.net 73
http://nalcoding.com 20
http://www.planet-php.org 10
http://www.netevil.org 10
http://btndw.blogspot.com 7
http://planet-php.org 7
http://localhost 6
http://www.phpeye.com 4
http://robing.xtools.co.nz 2
http://webcache.googleusercontent.com 2
http://test.idoc.vn 2
http://web.archive.org 1
http://localhost:3000 1
http://www.fbweb-test.comoj.com 1
http://www.linkedin.com 1
http://tournasdimitrios1.wordpress.com 1
http://phpeye.com 1
http://translate.googleusercontent.com 1
http://209.85.229.132 1
http://127.0.0.1:8795 1
http://64.233.183.104 1
http://www.pouik.net 1
http://lj-toys.com 1
http://static.slideshare.net 1
http://planet-php.net 1
http://74.125.95.132 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

PHP Data Objects Presentation Transcript

  • 1. PHP Data Objects Wez Furlong <wez@messagesystems.com>
  • 2. About me • PHP Core Developer since 2001 • Author of the Streams layer • I hold the title “King” of PECL • Author of most of PDO and its drivers
  • 3. What is PDO? • PHP Data Objects • A set of PHP extensions that provide a core PDO class and database specific drivers • Focus on data access abstraction rather than database abstraction
  • 4. What can it do? • Prepare/execute, bound parameters • Transactions • LOBS • SQLSTATE standard error codes, flexible error handling • Portability attributes to smooth over database specific nuances
  • 5. What databases are supported? • MySQL, PostgreSQL • ODBC, DB2, OCI • SQLite • Sybase/FreeTDS/MSSQL
  • 6. Connecting try { $dbh = new PDO($dsn, $user, $password, $options); } catch (PDOException $e) { die(“Failed to connect:” . $e->getMessage(); }
  • 7. DSNs • mysql:host=name;dbname=dbname • pgsql:host=name dbname=dbname • odbc:odbc_dsn • oci:dbname=dbname;charset=charset • sqlite:/path/to/file
  • 8. Connection Management try { $dbh = new PDO($dsn, $user, $pw); // use the database here // ... // done; release $dbh = null; } catch (PDOException $e) { die($e->getMessage(); }
  • 9. DSN Aliasing • uri:uri • Specify location of a file that contains the actual DSN on the first line • Works with the streams interface, so remote URLs can work too (this has performance implications) • name (with no colon) • Maps to pdo.dsn.name in your php.ini • pdo.dsn.name=sqlite:/path/to/name.db
  • 10. DSN Aliasing pdo.dsn.name=sqlite:/path/to/name.db $dbh = new PDO(“name”); is equivalent to: $dbh = new PDO(“sqlite:path/to/name.db”);
  • 11. Persistent Connections // Connection stays alive between requests $dbh = new PDO($dsn, $user, $pass, array( PDO::ATTR_PERSISTENT => true ) );
  • 12. Persistent Connections // Specify your own cache key $dbh = new PDO($dsn, $user, $pass, array( PDO::ATTR_PERSISTENT => “my-key” ) ); Useful for keeping separate persistent connections
  • 13. Persistent PDO The ODBC driver runs with connection pooling enabled by default. “better” than PHP-level persistence Pool is shared at the process level Can be forced off by setting: pdo_odbc.connection_pooling=off (requires that your web server be restarted)
  • 14. Error Handling • Maps error codes to ANSI SQLSTATE (5 character text string) • also provides the native db error information • Three error handling strategies • silent (default) • warning • exception
  • 15. PDO::ERRMODE_SILENT // The default mode if (!dbh->query($sql)) { echo $dbh->errorCode(), “<br>”; $info = $dbh->errorInfo(); // $info[0] == $dbh->errorCode() // SQLSTATE error code // $info[1] is driver specific err code // $info[2] is driver specific // error message }
  • 16. PDO::ERRMODE_WARNING $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); Behaves the same as silent mode Raises an E_WARNING as errors are detected Can suppress with @ operator as usual
  • 17. PDO::ERRMODE_EXCEPTION $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); try { $dbh->exec($sql); } catch (PDOException $e) { // display warning message print $e->getMessage(); $info = $e->errorInfo; // $info[0] == $e->code // SQLSTATE error code // $info[1] driver specific error code // $info[2] driver specific error string }
  • 18. Get data $dbh = new PDO($dsn); $stmt = $dbh->prepare( “SELECT * FROM FOO”); $stmt->execute(); while ($row = $stmt->fetch()) { print_r($row); } $stmt = null;
  • 19. Forward-only cursors • a.k.a. “unbuffered” queries in mysql parlance • They are the default cursor type • rowCount() doesn’t have meaning • FAST!
  • 20. Forward-only cursors • Other queries are likely to block • You must fetch all remaining data before launching another query • $stmt->closeCursor();
  • 21. Buffered Queries $dbh = new PDO($dsn); $stmt = $dbh->query(“SELECT * FROM FOO”); $rows = $stmt->fetchAll(); $count = count($rows); foreach ($rows as $row) { print_r($row); }
  • 22. Data typing • Very loose • Prefers strings • Gives you more control over data conversion
  • 23. Fetch modes • $stmt->fetch(PDO::FETCH_BOTH); - Array with numeric and string keys - default option • PDO::FETCH_NUM - numeric keys only • PDO::FETCH_ASSOC - string keys only
  • 24. Fetch modes • PDO::FETCH_OBJ - stdClass object - $obj->name == ‘name’ column • PDO::FETCH_CLASS - You choose the class • PDO::FETCH_INTO - You provide the object
  • 25. Fetch modes • PDO::FETCH_COLUMN - Fetches a column (example later) • PDO::FETCH_BOUND - Only fetches into bound variables • PDO::FETCH_FUNC - Returns the result filtered through a callback • see the manual for more
  • 26. Iterators $dbh = new PDO($dsn); $stmt = $dbh->query( “SELECT name FROM FOO”, PDO::FETCH_COLUMN, 0); foreach ($stmt as $name) { echo “Name: $namen”; } $stmt = null;
  • 27. Changing data $deleted = $dbh->exec( “DELETE FROM FOO WHERE 1”); $changes = $dbh->exec( “UPDATE FOO SET active=1 ” .“WHERE NAME LIKE ‘%joe%’”);
  • 28. Autonumber/sequences $dbh->exec( “insert into foo values (...)”); echo $dbh->lastInsertId(); $dbh->exec( “insert into foo values (...)”); echo $dbh->lastInsertId(“seqname”); Its up to you to call the right one for your db!
  • 29. Prepared Statements // No need to manually quote data here $stmt = $dbh->prepare( “INSERT INTO CREDITS (extension, name)” .“VALUES (:extension, :name)”); $stmt->execute(array( ‘extension’ => ‘xdebug’, ‘name’ => ‘Derick Rethans’ ));
  • 30. Prepared Statements // No need to manually quote data here $stmt = $dbh->prepare( “INSERT INTO CREDITS (extension, name)” .“VALUES (?, ?)”); $stmt->execute(array( ‘xdebug’, ‘Derick Rethans’ ));
  • 31. $db->quote() • If you really must quote things “by-hand” • $db->quote() adds quotes and proper escaping as needed • But doesn’t do anything in the ODBC driver! • Best to use prepared statements
  • 32. Transactions $dbh->beginTransaction(); try { $dbh->query(“UPDATE ...”); $dbh->query(“UPDATE ...”); $dbh->commit(); } catch (PDOException $e) { $dbh->rollBack(); }
  • 33. Stored Procedures $stmt = $dbh->prepare( “CALL sp_set_string(?)”); $stmt->execute(array(‘foo’)); $stmt = $dbh->prepare( “CALL sp_set_string(?)”); $stmt->bindValue(1, ‘foo’); $stmt->execute();
  • 34. OUT parameters $stmt = $dbh->prepare( “CALL sp_get_string(?)”); $stmt->bindParam(1, $ret, PDO::PARAM_STR, 4000); if ($stmt->execute()) { echo “Got $retn”; }
  • 35. IN/OUT parameters $stmt = $dbh->prepare( “call @sp_inout(?)”); $val = “My input data”; $stmt->bindParam(1, $val, PDO::PARAM_STR| PDO::PARAM_INPUT_OUTPUT, 4000); if ($stmt->execute()) { echo “Got $valn”; }
  • 36. Multi-rowset queries $stmt = $dbh->query( “call sp_multi_results()”); do { while ($row = $stmt->fetch()) { print_r($row); } } while ($stmt->nextRowset());
  • 37. Binding columns $stmt = $dbh->prepare( “SELECT extension, name from CREDITS”); if ($stmt->execute()) { $stmt->bindColumn(‘extension’, $ext); $stmt->bindColumn(‘name’, $name); while ($stmt->fetch(PDO::FETCH_BOUND)) { echo “Extension: $extn”; echo “Author: $namen”; } }
  • 38. Portability Aids • PDO aims to make it easier to write db independent apps • A number of hacks^Wtweaks for this purpose
  • 39. Oracle style NULLs • Oracle translates empty strings into NULLs • $dbh->setAttribute(PDO::ATTR_ORACLE_NULLS, true) • Translates empty strings into NULLs when fetching data • But won’t change them on insert
  • 40. Case folding • The ANSI SQL standard says that column names are returned in upper case • High end databases (eg: Oracle and DB2) respect this • Most others don’t • $dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER);
  • 41. LOBs • Large objects are usually >4kb in size • Nice to avoid fetching them until you need them • Mature RDBMS offer LOB APIs for this • PDO exposes LOBs as Streams
  • 42. Fetching an image $stmt = $dbh->prepare( “select contenttype, imagedata” .“ from images where id=?”); $stmt->execute(array($_GET[‘id’])); $stmt->bindColumn(1, $type, PDO::PARAM_STR, 256); $stmt->bindColumn(2, $lob, PDO::PARAM_LOB); $stmt->fetch(PDO::FETCH_BOUND); header(“Content-Type: $type”); fpassthru($lob);
  • 43. Uploading an image $stmt = $db->prepare(“insert into images ” . “(id, contenttype, imagedata)” . “ values (?,?,?)”); $id = get_new_id(); $fp = fopen($_FILES[‘file’][‘tmp_name’],‘rb’); $stmt->bindParam(1, $id); $stmt->bindParam(2, $_FILES[‘file’][‘type’]); $stmt->bindParam(3, $fp, PDO::PARAM_LOB); $stmt->execute();
  • 44. Scrollable Cursors • Allow random access to a rowset • Higher resource usage than forward-only cursors • Can be used for positioned updates (more useful for CLI/GUI apps)
  • 45. Positioned updates • An open (scrollable) cursor can be used to target a row for another query • Name your cursor by setting PDO::ATTR_CURSOR_NAME during prepare() • UPDATE foo set bar = ? WHERE CURRENT OF cursor_name
  • 46. Questions? • Find these slides on my blog and on slideshare.net • My blog: http://netevil.org/ • Gold: http://troels.arvin.dk/db/rdbms/#select-limit-offset