Php 101: PDO

2,083 views
1,983 views

Published on

Published in: Technology
1 Comment
13 Likes
Statistics
Notes
No Downloads
Views
Total views
2,083
On SlideShare
0
From Embeds
0
Number of Embeds
97
Actions
Shares
0
Downloads
223
Comments
1
Likes
13
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Php 101: PDO

    1. 1. PHP 101: PDO or:How I Learned to Stop Worrying and Love Data Access Abstraction Jeremy Kendall | Memphis PHP | July 26, 2012
    2. 2. What is PDO?• PDO == PHP Data Objects• Lightweight, consistent interface for accessing databases in PHP• Provides data access abstraction, not database abstraction• Ships with PHP 5.1• PECL extension for 5.0
    3. 3. Drivers include . . .• MySQL• PostgreSQL• SQL Server• SQLite• and more . . .
    4. 4. Which drivers do I have?• var_dump(PDO::getAvailableDrivers());• If you don’t see what you need, check php.ini
    5. 5. Working with databases• Solved problem, you don’t have to write anything yourself• PHP and MySQL have an especially rich history• CRUD is the easy part• Creating clean, maintainable code is the challenge
    6. 6. Let’s look at sometypical procedural code
    7. 7. What we’re building
    8. 8. mysql<?php$conn = mysql_connect(localhost, testuser, testpass) or die(Could not connect: . mysql_error());mysql_select_db(bookshelf) or die(Could not select bookshelf);$result = mysql_query(SELECT * FROM bookshelf ORDER BY title, $conn) or die(Invalid query: . mysql_error());?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = mysql_fetch_assoc($result)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpmysql_close($conn);
    9. 9. mysql<?php$conn = mysql_connect(localhost, testuser, testpass) or die(Could not connect: . mysql_error());mysql_select_db(bookshelf) or die(Could not select bookshelf);$result = mysql_query(SELECT * FROM bookshelf ORDER BY title, $conn) or die(Invalid query: . mysql_error());?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = mysql_fetch_assoc($result)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpmysql_close($conn);
    10. 10. mysql<?php$conn = mysql_connect(localhost, testuser, testpass) or die(Could not connect: . mysql_error());mysql_select_db(bookshelf) or die(Could not select bookshelf);$result = mysql_query(SELECT * FROM bookshelf ORDER BY title, $conn) or die(Invalid query: . mysql_error());?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = mysql_fetch_assoc($result)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpmysql_close($conn);
    11. 11. mysql<?php$conn = mysql_connect(localhost, testuser, testpass) or die(Could not connect: . mysql_error());mysql_select_db(bookshelf) or die(Could not select bookshelf);$result = mysql_query(SELECT * FROM bookshelf ORDER BY title, $conn) or die(Invalid query: . mysql_error());?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = mysql_fetch_assoc($result)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpmysql_close($conn);
    12. 12. mysql<?php$conn = mysql_connect(localhost, testuser, testpass) or die(Could not connect: . mysql_error());mysql_select_db(bookshelf) or die(Could not select bookshelf);$result = mysql_query(SELECT * FROM bookshelf ORDER BY title, $conn) or die(Invalid query: . mysql_error());?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = mysql_fetch_assoc($result)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpmysql_close($conn);
    13. 13. mysql<?php$conn = mysql_connect(localhost, testuser, testpass) or die(Could not connect: . mysql_error());mysql_select_db(bookshelf) or die(Could not select bookshelf);$result = mysql_query(SELECT * FROM bookshelf ORDER BY title, $conn) or die(Invalid query: . mysql_error());?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = mysql_fetch_assoc($result)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpmysql_close($conn);
    14. 14. Oops!Should have used mysqli!
    15. 15. mysqli<?php$conn = mysqli_connect(localhost, testuser, testpass, bookshelf) or die(Could not connect: . mysqli_connect_error());$result = mysqli_query($conn, SELECT * FROM bookshelf ORDER BY title) or die(Invalid query: . mysqli_error($conn));?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = mysqli_fetch_assoc($result)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpmysqli_close($conn);
    16. 16. Refactoring problems// You cant simply find and replace// because of differences in the interfaces// mysql_query wants query first and connection second$result = mysql_query($query, $conn);// mysqli_query is exactly opposite$result = mysqli_query($conn, $query);
    17. 17. Refactoring problems// You cant simply find and replace// because of differences in the interfaces// mysql_query wants query first and connection second$result = mysql_query($query, $conn);// mysqli_query is exactly opposite$result = mysqli_query($conn, $query);
    18. 18. Refactoring problems// You cant simply find and replace// because of differences in the interfaces// mysql_query wants query first and connection second$result = mysql_query($query, $conn);// mysqli_query is exactly opposite$result = mysqli_query($conn, $query);
    19. 19. Changing DB vendors? Have fun with that.
    20. 20. sqlsrv<?php$connectionInfo = array( Database => bookshelf, UID => testuser, PWD => testpass);$conn = sqlsrv_connect(serverNameinstanceName, $connectionInfo);$stmt = sqlsrv_query($conn, SELECT * FROM bookshelf ORDER BY title);?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpsqlsrv_close($conn);
    21. 21. sqlsrv<?php$connectionInfo = array( Database => bookshelf, UID => testuser, PWD => testpass);$conn = sqlsrv_connect(serverNameinstanceName, $connectionInfo);$stmt = sqlsrv_query($conn, SELECT * FROM bookshelf ORDER BY title);?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpsqlsrv_close($conn);
    22. 22. sqlsrv<?php$connectionInfo = array( Database => bookshelf, UID => testuser, PWD => testpass);$conn = sqlsrv_connect(serverNameinstanceName, $connectionInfo);$stmt = sqlsrv_query($conn, SELECT * FROM bookshelf ORDER BY title);?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpsqlsrv_close($conn);
    23. 23. sqlsrv<?php$connectionInfo = array( Database => bookshelf, UID => testuser, PWD => testpass);$conn = sqlsrv_connect(serverNameinstanceName, $connectionInfo);$stmt = sqlsrv_query($conn, SELECT * FROM bookshelf ORDER BY title);?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpsqlsrv_close($conn);
    24. 24. sqlsrv<?php$connectionInfo = array( Database => bookshelf, UID => testuser, PWD => testpass);$conn = sqlsrv_connect(serverNameinstanceName, $connectionInfo);$stmt = sqlsrv_query($conn, SELECT * FROM bookshelf ORDER BY title);?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table><?phpsqlsrv_close($conn);
    25. 25. But what can you do about it?
    26. 26. You could roll your own<?phpclass MyDb{ public function __construct($host, $username, $password, $dbname) { } public function query($sql, array $bind) { } // . . .}
    27. 27. Or don’t and use PDO
    28. 28. <?php$dsn = mysql:host=localhost;dbname=bookshelf;$username = testuser;$password = testpass;$options = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);try { $dbh = new PDO($dsn, $username, $password, $options);} catch (PDOException $e) { echo Error!: . $e->getMessage(); die();}// $result is an array, so we can use array functions rather than db vendor functions$result = $dbh->query(SELECT * FROM bookshelf ORDER BY title)->fetchAll();?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php foreach ($result as $row) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table>
    29. 29. <?php$dsn = mysql:host=localhost;dbname=bookshelf;$username = testuser;$password = testpass;$options = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);try { $dbh = new PDO($dsn, $username, $password, $options);} catch (PDOException $e) { echo Error!: . $e->getMessage(); die();}// $result is an array, so we can use array functions rather than db vendor functions$result = $dbh->query(SELECT * FROM bookshelf ORDER BY title)->fetchAll();?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php foreach ($result as $row) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table>
    30. 30. <?php$dsn = mysql:host=localhost;dbname=bookshelf;$username = testuser;$password = testpass;$options = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);try { $dbh = new PDO($dsn, $username, $password, $options);} catch (PDOException $e) { echo Error!: . $e->getMessage(); die();}// $result is an array, so we can use array functions rather than db vendor functions$result = $dbh->query(SELECT * FROM bookshelf ORDER BY title)->fetchAll();?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php foreach ($result as $row) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table>
    31. 31. <?php$dsn = mysql:host=localhost;dbname=bookshelf;$username = testuser;$password = testpass;$options = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);try { $dbh = new PDO($dsn, $username, $password, $options);} catch (PDOException $e) { echo Error!: . $e->getMessage(); die();}// $result is an array, so we can use array functions rather than db vendor functions$result = $dbh->query(SELECT * FROM bookshelf ORDER BY title)->fetchAll();?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php foreach ($result as $row) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table>
    32. 32. <?php$dsn = mysql:host=localhost;dbname=bookshelf;$username = testuser;$password = testpass;$options = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);try { $dbh = new PDO($dsn, $username, $password, $options);} catch (PDOException $e) { echo Error!: . $e->getMessage(); die();}// $result is an array, so we can use array functions rather than db vendor functions$result = $dbh->query(SELECT * FROM bookshelf ORDER BY title)->fetchAll();?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php foreach ($result as $row) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table>
    33. 33. <?php$dsn = mysql:host=localhost;dbname=bookshelf;$username = testuser;$password = testpass;$options = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);try { $dbh = new PDO($dsn, $username, $password, $options);} catch (PDOException $e) { echo Error!: . $e->getMessage(); die();}// $result is an array, so we can use array functions rather than db vendor functions$result = $dbh->query(SELECT * FROM bookshelf ORDER BY title)->fetchAll();?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php foreach ($result as $row) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table>
    34. 34. <?php$dsn = mysql:host=localhost;dbname=bookshelf;$username = testuser;$password = testpass;$options = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);try { $dbh = new PDO($dsn, $username, $password, $options);} catch (PDOException $e) { echo Error!: . $e->getMessage(); die();}// $result is an array, so we can use array functions rather than db vendor functions$result = $dbh->query(SELECT * FROM bookshelf ORDER BY title)->fetchAll();?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php foreach ($result as $row) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table>
    35. 35. But I’m going to use SQLite in DEV . . .
    36. 36. No problem!Change the dsn, username, and password. Done. $dsn = mysql:host=localhost;dbname=bookshelf; $username = testuser; $password = testpass; becomes $dsn = sqlite: . realpath(./data/db/bookshelf.db); $username = null; $password = null;
    37. 37. Connecting• DSN required, username & pass optional• A connection error always throws an Exception, so use try/catch• Closing a connection is as simple as $dbh = null
    38. 38. Errors and Exceptions• Three error modes • PDO::ERRMODE_SILENT • PDO::ERRMODE_WARNING • PDO::ERRMODE_EXCEPTION• Always use exceptions• No, really, use exceptions
    39. 39. Insert, Update, Delete• PDO::exec()• Returns # rows affected• Won’t return results of SELECT• Won’t escape data (use PDO::quote())
    40. 40. Delete example/* quote string */$title = $dbh->quote(Refactoring);/* Delete a book */$count = $dbh->exec("DELETE FROM bookshelf WHERE title = $title");/* Return number of rows that were deleted */print("Deleted $count rows.n");
    41. 41. Delete example/* quote string */$title = $dbh->quote(Refactoring);/* Delete a book */$count = $dbh->exec("DELETE FROM bookshelf WHERE title = $title");/* Return number of rows that were deleted */print("Deleted $count rows.n");
    42. 42. Delete example/* quote string */$title = $dbh->quote(Refactoring);/* Delete a book */$count = $dbh->exec("DELETE FROM bookshelf WHERE title = $title");/* Return number of rows that were deleted */print("Deleted $count rows.n");
    43. 43. Delete example/* quote string */$title = $dbh->quote(Refactoring);/* Delete a book */$count = $dbh->exec("DELETE FROM bookshelf WHERE title = $title");/* Return number of rows that were deleted */print("Deleted $count rows.n");
    44. 44. In almost all cases, favor prepared statements over PDO::exec()
    45. 45. Prepared statements• To know them is to love them• No more SQL injection• Can execute same statement multiple times with different values• Efficient (in most cases)• Positional, named• The one feature PDO emulates
    46. 46. Prepared statements Using named parameters:$sql = "INSERT INTO bookshelf (title, author) VALUES (:title, :author)";$statement = $dbh->prepare($sql);$statement->bindParam(title, $title);$statement->bindParam(author, $author);$books = array( "Clean Code" => "Robert C. Martin", "Refactoring" => "Martin Fowler", "Test-Driven Development" => "Kent Beck", "The Agile Samurai" => "Jonathan Rasmusson", "Working Effectively with Legacy Code" => "Michael Feathers");foreach ($books as $title => $author) { $setup->execute();}
    47. 47. Prepared statements Using named parameters:$sql = "INSERT INTO bookshelf (title, author) VALUES (:title, :author)";$statement = $dbh->prepare($sql);$statement->bindParam(title, $title);$statement->bindParam(author, $author);$books = array( "Clean Code" => "Robert C. Martin", "Refactoring" => "Martin Fowler", "Test-Driven Development" => "Kent Beck", "The Agile Samurai" => "Jonathan Rasmusson", "Working Effectively with Legacy Code" => "Michael Feathers");foreach ($books as $title => $author) { $setup->execute();}
    48. 48. Prepared statements Using named parameters:$sql = "INSERT INTO bookshelf (title, author) VALUES (:title, :author)";$statement = $dbh->prepare($sql);$statement->bindParam(title, $title);$statement->bindParam(author, $author);$books = array( "Clean Code" => "Robert C. Martin", "Refactoring" => "Martin Fowler", "Test-Driven Development" => "Kent Beck", "The Agile Samurai" => "Jonathan Rasmusson", "Working Effectively with Legacy Code" => "Michael Feathers");foreach ($books as $title => $author) { $setup->execute();}
    49. 49. Prepared statements Using named parameters:$sql = "INSERT INTO bookshelf (title, author) VALUES (:title, :author)";$statement = $dbh->prepare($sql);$statement->bindParam(title, $title);$statement->bindParam(author, $author);$books = array( "Clean Code" => "Robert C. Martin", "Refactoring" => "Martin Fowler", "Test-Driven Development" => "Kent Beck", "The Agile Samurai" => "Jonathan Rasmusson", "Working Effectively with Legacy Code" => "Michael Feathers");foreach ($books as $title => $author) { $setup->execute();}
    50. 50. Prepared statements Using positional parameters:$sql = "INSERT INTO bookshelf (title, author) VALUES (?, ?)";$statement = $dbh->prepare($sql);$statement->bindParam(1, $title);$statement->bindParam(2, $author);$books = array( "Clean Code" => "Robert C. Martin", "Refactoring" => "Martin Fowler", "Test-Driven Development" => "Kent Beck", "The Agile Samurai" => "Jonathan Rasmusson", "Working Effectively with Legacy Code" => "Michael Feathers");foreach ($books as $title => $author) { $setup->execute();}
    51. 51. Prepared statements Array of named params to PDO::execute$sql = "INSERT INTO bookshelf (title, author) VALUES (:title, :author)";$statement = $dbh->prepare($sql);$statement->execute(array(title => $title, author => $author));
    52. 52. Prepared statements Array of named params to PDO::execute$sql = "INSERT INTO bookshelf (title, author) VALUES (:title, :author)";$statement = $dbh->prepare($sql);$statement->execute(array(title => $title, author => $author));
    53. 53. Prepared statements Array of named params to PDO::execute$sql = "INSERT INTO bookshelf (title, author) VALUES (:title, :author)";$statement = $dbh->prepare($sql);$statement->execute(array(title => $title, author => $author));
    54. 54. Select• Gets data from the database• Results returned as PDOStatement• How data is fetched from statement depends on fetch mode• Grab all results at once with fetchAll()
    55. 55. Fetch modes• Can be set in constructor or later with PDO::setAttribute() or PDOStatement::setFetchMode()• PDO::FETCH_ASSOC• PDO::FETCH_BOTH (default)• PDO::FETCH_NUM• PDO::FETCH_OBJ• to name a few . . .
    56. 56. Fetching// Gets all books in database$stmt = $dbh->query("SELECT * FROM bookshelf ORDER BY title");// Returns array of all results$books = $stmt->fetchAll();// Returns next row in manner determined by fetch mode$row = $stmt->fetch();// Can choose fetch mode at time of fetch$row = $stmt->fetch(PDO::FETCH_OBJ);
    57. 57. Fetching// Gets all books in database$stmt = $dbh->query("SELECT * FROM bookshelf ORDER BY title");// Returns array of all results$books = $stmt->fetchAll();// Returns next row in manner determined by fetch mode$row = $stmt->fetch();// Can choose fetch mode at time of fetch$row = $stmt->fetch(PDO::FETCH_OBJ);
    58. 58. Fetching// Gets all books in database$stmt = $dbh->query("SELECT * FROM bookshelf ORDER BY title");// Returns array of all results$books = $stmt->fetchAll();// Returns next row in manner determined by fetch mode$row = $stmt->fetch();// Can choose fetch mode at time of fetch$row = $stmt->fetch(PDO::FETCH_OBJ);
    59. 59. Fetching// Gets all books in database$stmt = $dbh->query("SELECT * FROM bookshelf ORDER BY title");// Returns array of all results$books = $stmt->fetchAll();// Returns next row in manner determined by fetch mode$row = $stmt->fetch();// Can choose fetch mode at time of fetch$row = $stmt->fetch(PDO::FETCH_OBJ);
    60. 60. Fetching// Gets all books in database$stmt = $dbh->query("SELECT * FROM bookshelf ORDER BY title");// Returns array of all results$books = $stmt->fetchAll();// Returns next row in manner determined by fetch mode$row = $stmt->fetch();// Can choose fetch mode at time of fetch$row = $stmt->fetch(PDO::FETCH_OBJ);
    61. 61. Fetching PDOStatement implements Traversable, which allows you to:$stmt = $dbh->query(SELECT * FROM bookshelf ORDER BY title);?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php foreach ($stmt as $row) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table>
    62. 62. Fetching PDOStatement implements Traversable, which allows you to:$stmt = $dbh->query(SELECT * FROM bookshelf ORDER BY title);?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php foreach ($stmt as $row) { echo "<tr>"; echo "<td>{$row[title]}</td><td>{$row[author]}</td>"; echo "</tr>"; } ?></table>
    63. 63. Fetching PDO::FETCH_BOUND is slick$stmt = $dbh->query(SELECT id, title, author FROM bookshelf ORDER BY title);$stmt->bindColumn(title, $title);$stmt->bindColumn(author, $author);?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($stmt->fetch(PDO::FETCH_BOUND)) { echo "<tr>"; echo "<td>$title</td><td>$author</td>"; echo "</tr>"; } ?></table>
    64. 64. Fetching PDO::FETCH_BOUND is slick$stmt = $dbh->query(SELECT id, title, author FROM bookshelf ORDER BY title);$stmt->bindColumn(title, $title);$stmt->bindColumn(author, $author);?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($stmt->fetch(PDO::FETCH_BOUND)) { echo "<tr>"; echo "<td>$title</td><td>$author</td>"; echo "</tr>"; } ?></table>
    65. 65. Fetching PDO::FETCH_BOUND is slick$stmt = $dbh->query(SELECT id, title, author FROM bookshelf ORDER BY title);$stmt->bindColumn(title, $title);$stmt->bindColumn(author, $author);?><table> <tr> <th>Title</th><th>Author</th> </tr> <?php while ($stmt->fetch(PDO::FETCH_BOUND)) { echo "<tr>"; echo "<td>$title</td><td>$author</td>"; echo "</tr>"; } ?></table>
    66. 66. But wait, there’s more!
    67. 67. PDO::lastInsertId()• Returns the ID of the last inserted row• Or the last value from a sequence object• Be careful, some databases don’t support this and may exhibit unexpected behavior
    68. 68. Transactions• PDO::beginTransaction()• PDO::commit()• PDO::rollback()• Check your DB documentation for support
    69. 69. Benefits• Maintainability• Portability (with a few vendor specific caveats)• Safety (prepared statements)• Object oriented
    70. 70. Drawbacks• Not all vendor specific features supported• Interface is almost the same for all databases• Slower in some cases• Mediocre Oracle support (who uses Oracle?)
    71. 71. Portable, mostly• Every DB has its own oddities and gotchas• PDO offers data access abstraction• You’ll likely still have to tweak if you’re doing anything other than very simple CRUD• Still better than mysql_*, mysqli_*, sqlsrv_*• Choose a DBAL like Doctrine if you need more
    72. 72. Credits• PHP Data Objects by Wez Furlong: http:// www.slideshare.net/wezfurlong/php-data-objects• Nettuts+: http://net.tutsplus.com/tutorials/php/why-you- should-be-using-phps-pdo-for-database-access/• Introduction to PDO: http://www.dreamincode.net/ forums/topic/214733-introduction-to-pdo/• php.net: http://us.php.net/manual/en/class.pdo.php
    73. 73. Questions?
    74. 74. Thanks!• @JeremyKendall• jeremy@jeremykendall.net• http://about.me/jeremykendall

    ×