Try Tuts+ Premium, Get Cash Back!
PHP Database Access: Are You Doing It Correctly?

PHP Database Access: Are You Doing It Correctly?

Tutorial Details
  • Topic - Database Access in PHP
  • Difficulty - Moderate

We've covered PHP's PDO API a couple of times here on Nettuts+, but, generally, those articles focused more on the theory, and less on the application. This article will fix that!

To put it plainly, if you're still using PHP's old mysql API to connect to your databases, read on!


What?

It's possible that, at this point, the only thought in your mind is, "What the heck is PDO?" Well, it's one of PHP's three available APIs for connecting to a MySQL database. "Three," you say? Yes; many folks don't know it, but there are three different APIs for connecting:

  • mysql
  • mysqli – MySQL Improved
  • pdo – PHP Data Objects

The traditional mysql API certainly gets the job done, and has become so popular largely due to the fact that it makes the process of retrieving some records from a database as easy as possible. For example:

/*
 * Anti-Pattern
 */

# Connect
mysql_connect('localhost', 'username', 'password') or die('Could not connect: ' . mysql_error());

# Choose a database
mysql_select_db('someDatabase') or die('Could not select database');

# Perform database query
$query = "SELECT * from someTable";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());

# Filter through rows and echo desired information
while ($row = mysql_fetch_object($result)) {
    echo $row->name;
}

Yes, the code above is fairly simple, but it does come with its significant share of downsides.

  • Deprecated: Though it hasn't been officially deprecated – due to widespread use – in terms of best practice and education, it might as well be.
  • Escaping: The process of escaping user input is left to the developer – many of which don't understand or know how to sanitize the data.
  • Flexibility: The API isn't flexible; the code above is tailor-made for working with a MySQL database. What if you switch?

PDO, or PHP Data Objects, provides a more powerful API that doesn't care about the driver you use; it's database agnostic. Further, it offers the ability to use prepared statements, virtually eliminating any worry of SQL injection.


How?

When I was first learning about the PDO API, I must admit that it was slightly intimidating. This wasn't because the API was overly complicated (it's not) – it's just that the old myqsl API was so dang easy to use!

Don't worry, though; follow these simple steps, and you'll be up and running in no time.

Connect

So you already know the legacy way of connecting to a MySQL database:

# Connect
mysql_connect('localhost', 'username', 'password') or die('Could not connect: ' . mysql_error());

With PDO, we create a new instance of the class, and specify the driver, database name, username, and password – like so:

$conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);

Don't let that long string confuse you; it's really very simple: we specify the name of the driver (mysql, in this case), followed by the required details (connection string) for connecting to it.

What's nice about this approach is that, if we instead wish to use a sqlite database, we simply update the DSN, or "Data Source Name," accordingly; we're not dependent upon MySQL in the way that we are when use functions, like mysql_connect.

Errors

But, what if there's an error, and we can't connect to the database? Well, let's wrap everything within a try/catch block:

try {
    $conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}

That's better! Please note that, by default, the default error mode for PDO is PDO::ERRMODE_SILENT. With this setting left unchanged, you'll need to manually fetch errors, after performing a query.

echo $conn->errorCode();
echo $conn->errorInfo();

Instead, a better choice, during development, is to update this setting to PDO::ERRMODE_EXCEPTION, which will fire exceptions as they occur. This way, any uncaught exceptions will halt the script.

For reference, the available options are:

  • PDO::ERRMODE_SILENT
  • PDO::ERRMODE_WARNING
  • PDO::ERRMODE_EXCEPTION

Fetch

At this point, we've created a connection to the database; let's fetch some information from it. There's two core ways to accomplish this task: query and execute. We'll review both.

Query

/*
 * The Query Method
 * Anti-Pattern
 */

$name = 'Joe'; # user-supplied data

try {
    $conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $data = $conn->query('SELECT * FROM myTable WHERE name = ' . $conn->quote($name));

    foreach($data as $row) {
        print_r($row); 
    }
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}

Though this works, notice that we're still manually escaping the user's data with the PDO::quote method. Think of this method as, more or less, the PDO equivalent to use mysql_real_escape_string; it will both escape and quote the string that you pass to it. In situations, when you're binding user-supplied data to a SQL query, it's strongly advised that you instead use prepared statements. That said, if your SQL queries are not dependent upon form data, the query method is a helpful choice, and makes the process of looping through the results as easy as a foreach statement.

Prepared Statements

/*
 * The Prepared Statements Method
 * Best Practice
 */

$id = 5;
try {
    $conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);    
    
    $stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
    $stmt->execute(array('id' => $id));

    while($row = $stmt->fetch()) {
        print_r($row);
    }
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}

In this example, we're using the prepare method to, literally, prepare the query, before the user's data has been attached. With this technique, SQL injection is virtually impossible, because the data doesn't ever get inserted into the SQL query, itself. Notice that, instead, we use named parameters (:id) to specify placeholders.

Alternatively, you could use ? parameters, however, it makes for a less-readable experience. Stick with named parameters.

Next, we execute the query, while passing an array, which contains the data that should be bound to those placeholders.

$stmt->execute(array('id' => $id));

An alternate, but perfectly acceptable, approach would be to use the bindParam method, like so:

$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();

Specifying the Ouput

After calling the execute method, there are a variety of different ways to receive the data: an array (the default), an object, etc. In the example above, the default response is used: PDO::FETCH_ASSOC; this can easily be overridden, though, if necessary:

while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
    print_r($row);
}

Now, we've specified that we want to interact with the result set in a more object-oriented fashion. Available choices include, but not limited to:

  • PDO::FETCH_ASSOC: Returns an array.
  • PDO::FETCH_BOTH: Returns an array, indexed by both column-name, and 0-indexed.
  • PDO::FETCH_BOUND: Returns TRUE and assigns the values of the columns in your result set to the PHP variables to which they were bound.
  • PDO::FETCH_CLASS: Returns a new instance of the specified class.
  • PDO::FETCH_OBJ: Returns an anonymous object, with property names that correspond to the columns.

One problem with the code above is that we aren't providing any feedback, if no results are returned. Let's fix that:

$stmt->execute(array('id' => $id));

# Get array containing all of the result rows
$result = $stmt->fetchAll();

# If one or more rows were returned...
if ( count($result) ) {
    foreach($result as $row) {
        print_r($row);
    }
} else {
    echo "No rows returned.";
}

At this point, our full code should look like so:

 
  $id = 5;
  try {
    $conn = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
    $stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
    $stmt->execute(array('id' => $id));

    $result = $stmt->fetchAll();

    if ( count($result) ) { 
      foreach($result as $row) {
        print_r($row);
      }   
    } else {
      echo "No rows returned.";
    }
  } catch(PDOException $e) {
      echo 'ERROR: ' . $e->getMessage();
  }

Multiple Executions

The PDO extension becomes particularly powerful when executing the same SQL query multiple times, but with different parameters.

try {
  $conn = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
  $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  # Prepare the query ONCE
  $stmt = $conn->prepare('INSERT INTO someTable VALUES(:name)');
  $stmt->bindParam(':name', $name);

  # First insertion
  $name = 'Keith';
  $stmt->execute();

  # Second insertion
  $name = 'Steven';
  $stmt->execute();
} catch(PDOException $e) {
  echo $e->getMessage();
}

Once the query has been prepared, it can be executed multiple times, with different parameters. The code above will insert two rows into the database: one with a name of “Kevin,” and the other, “Steven.”


CRUD

Now that you have the basic process in place, let’s quickly review the various CRUD tasks. As you’ll find, the required code for each is virtually identical.

Create (Insert)

try {
  $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  $stmt = $pdo->prepare('INSERT INTO someTable VALUES(:name)');
  $stmt->execute(array(
    ':name' => 'Justin Bieber'
  ));

  # Affected Rows?
  echo $stmt->rowCount(); // 1
} catch(PDOException $e) {
  echo 'Error: ' . $e->getMessage();

Update

$id = 5;
$name = "Joe the Plumber";

try {
  $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  $stmt = $pdo->prepare('UPDATE someTable SET name = :name WHERE id = :id');
  $stmt->execute(array(
    ':id'   => $id,
    ':name' => $name
  ));
  
  echo $stmt->rowCount(); // 1
} catch(PDOException $e) {
  echo 'Error: ' . $e->getMessage();
}

Delete

$id = 5; // From a form or something similar

try {
  $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  $stmt = $pdo->prepare('DELETE FROM someTable WHERE id = :id');
  $stmt->bindParam(':id', $id); // this time, we'll use the bindParam method
  $stmt->execute();
  
  echo $stmt->rowCount(); // 1
} catch(PDOException $e) {
  echo 'Error: ' . $e->getMessage();
}

Object Mapping

One of the neatest aspects of PDO (mysqli, as well) is that it gives us the ability to map the query results to a class instance, or object. Here’s an example:

class User {
  public $first_name;
  public $last_name;

  public function full_name()
  {
    return $this->first_name . ' ' . $this->last_name;
  }
}

try {
  $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  $result = $pdo->query('SELECT * FROM someTable');

  # Map results to object
  $result->setFetchMode(PDO::FETCH_CLASS, 'User');

  while($user = $result->fetch()) {
    # Call our custom full_name method
    echo $user->full_name();
  }
} catch(PDOException $e) {
  echo 'Error: ' . $e->getMessage();
}

Closing Thoughts

Bottom line: if you’re still using that old mysql API for connecting to your databases, stop. Though it hasn’t yet been deprecated, in terms of education and documentation, it might as well be. Your code will be significantly more secure and streamlined if you adopt the PDO extension.

Tags: Databases
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Peter Gyarmati

    Great tutorial, thanks.

  • Andrew

    Awesome, after this one i’m upgrading my database class to PDO.
    Only 1 question how to force to use UTF-8 on connection or query?

    • EllisGL

      After connecting, run the following query:
      SET NAMES ‘utf8′

    • http://sidisinsane.com Dirk Sidney Jansen

      You can force UTF-8 by adding an option to your connection like this:

      $options = array (
      PDO::MYSQL_ATTR_INIT_COMMAND => ‘SET NAMES utf8′
      );
      $pdo = new PDO(‘mysql:host=localhost;dbname=someDatabase’, $username, $password, $options);

    • Sergey

      Note that you most likely can specify this in database configuration, that way you don’t have to run extra query every time your app establishes a connection.

      • EllisGL

        @sergey:That’s if you have access to the my.cnf file.

  • Austin Hampton

    Thanks so much for this walk through Jeff, been looking around for a simple quick read about PDO for a while now.

  • Mike McRorey

    Thanks for putting this together.

  • EllisGL

    When you bind with “PDO::PARAM_INT” don’t forget to cast the value you are passing as an int.
    $stmt->bindParam(‘:id’, (int) $id, PDO::PARAM_INT);

    If you don’t, it will put quotes around the value and create a less optimized query.

  • Sarvesh

    Do you know Jeffrey, you are awesome.

    May God bless you.

    Thanks
    Sarvesh Kesharwani

  • Shibbir

    thanks Jeffery. that will help me :)

  • eanimator

    What about mysqli? You havent explained it.

    Question is: Lets say, I have a small-medium web app with SQL queries (mysql – depreciated based) now how do I migrate all these queries to support PDO param binding?

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      mysqli is a fine choice, but I’d recommend that people instead use PDO.

      • http://wouterj.nl Wouter J

        I don’t think MySQLi is a fine choice. It has a bad prepared statement machine (no placeholder names for instance) and it looks like they have putted the mysql_* API into a class API without changing anything usefull.

      • Justin

        Could anyone go into some detail (or links to some good articles) of why mysqli prepared statements are not as good as PDO? I recently did a project using mysqli prepared statements so it would be nice to hear some benefits before I think about changing it (internal project luckily, so time/budget is less of an issue).

      • http://www.jeffrey-way.com Jeffrey Way
        Author

        We posted an article about it not too long ago. :)

        http://net.tutsplus.com/tutorials/php/pdo-vs-mysqli-which-should-you-use/

      • http://reconnect-inc.com/ David D’hont

        You know you people really should do more research. Because I have been doing research about this ever since Jeffrey’s first article and there are many things I disagree upon.

        “Here’s something else to keep in mind: For now (PHP 5.2) the PDO library is buggy. It’s full of strange bugs”

        And I can attest to this, when I first tried out PDO, I simply didn’t use it because there were so many unexpected buggy results. Things that should work caused unexpected results that deviated from the tutorials I was reading. So if your version is one where PDO is buggy then what’s the use.

        I’m all for moving forward though, I have a better PHP version now on my Private server and keep it up to date always. So I prefer using PDO as it does indeed have advantages over other options. So if you are working on a new project, and you have the latest version. By all means, use PDO.

        Named Parameters are NOT better then Placeholders. Placeholders work equally as good. And in the end, no one who does not know MySQL is going to touch your written queries. So stop pretending like it makes a difference. The only difference I know it makes, is it saves me a huge bunch of extra code. And that is all I need to know to make my choice between Named Parameters and Placeholders.

        MySQLi prepared statements are just as good, and if you only use MySQL then you don’t need to update just for the sake of PDO. If you guys are only going to use MySQL. Which I suspect most will then changing “just because” is simply not worth it.

        The world doesn’t reward perfectionists. It rewards people who gets things done. You already chose MySQL as your database, so unless you are building a CMS or something along the lines, then you don’t really need to upgrade.

        When the time comes you want to update. It won’t be such a difficult task. And to quote Jeffrey Way:
        MySQLi is a fine choice.

    • http://reconnect-inc.com/ David D’hont

      Something along the lines of this. I left the Try / Catch out of it since Jeffrey has already made an excellent example of that.

      mysql_connect(‘localhost’, ‘username’, ‘password’) or die(‘Could not connect: ‘ . mysql_error());

      To:

      $conn = new PDO(‘mysql:host=localhost;dbname=myDatabase’, $username, $password);

      $query = mysql_query(“SELECT * FROM fruit WHERE calories < '$calories' AND colour = '$colour'")or die(mysql_error());

      while($row = mysql_fetch_assoc($query))
      {
      print_r($row);
      }

      To:

      $sth = $dbh->prepare(‘SELECT * FROM fruit WHERE calories execute(array($calories, $colour));

      while($row = $stmt->fetch()) {
      print_r($row);
      }

      • http://reconnect-inc.com David D’hont

        And there goes the so called PRE support, Envato really should really consider a simple Markup Editor for the comment section. MarkitUp wouldn’t hurt….

  • SPeed_FANat1c

    “Escaping: The process of escaping user input is left to the developer – many of which don’t understand or know how to sanitize the data.”

    If you use some framework like codeigniter, you don’t need to worry. Probably the same is with other frameworks. And I don’t see a reason not to use framework, at least until now.

    • Adrian Oprea

      Yes, you are right, but don’t we have to at least KNOW how the framework is implementing this ? I think Jeff’s point here was that there are many developers that don’t even know what escaping user input is. And those are the developers that get phoned in the middle of the night by their customer, telling them that their site just got hacked. Great article Jeff !

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Well, yeah, a framework provides a helpful abstraction. But the goal is to understand how to do it without the help of a framework.

  • alireza mamaghani

    Thanks so very much for this walk through Jeff.

  • http://www.facebook.com/rathod.hemal Hemal

    The best and easiest tutorial about PHP and Database I have come across.
    Thanks Jeffrey

  • azb

    PDO is much like data access abstraction library, defined a unified interface for creating and maintaining database connections, issue queries, quoting parameters, traversing result sets, deal with prepare statements and error handling but does it compare with PEAR package or MDB2 which has richer functionality of advanced database abstraction

  • Mario

    I’m curious, is Codeigniter’s active record class just as good, better or worse than PDO?

    • N3rD

      Codeigniter doesn’t do real “prepared statement” even if it provides a query bind method where you can actually use placeholders (?) inside a query, but the difference is that PDO when you prepare some query will send a command to the Database server with the FULL query, when you call the execute method PDO will send ONLY the values to bind!!! That’s why PDO has a really good shield against 1st order sql injection! Of course for 2nd order you need to sanitize and use some other control system!

      • Mario

        I see. In that case, here’s hoping Nettuts can show us how to use them both because man, I love CI.

  • http://wernancheta.wordpress.com Wern Ancheta

    Thanks for this awesome introduction on using PDO especially the multiple execution and object mapping part. You definitely sparked some interest in using this database API. Just a question though, how would this compare to the database classes used in frameworks like CodeIgniter and CakePHP in terms of performance and security?

  • http://www.serveradminblog.com SAB

    You can use this trick to set UTF-8

    http://www.serveradminblog.com/2011/10/utf-8-with-mysql-and-pdo/ (MYSQL_ATTR_INIT_COMMAND is your friend :) )

  • Nick Mok

    Great tutorial. This is probably the only tutorial which covers how you do prepared statements for Select queries, while most just cover insert.

    Thanks again!

  • http://nmsdvid.com David Nemes

    I read somewhere that the PDO API is little bit slower than the mysql API. This is true ?

    • john

      I ran some benchmarks and found that the performance hit was about double to three times execution speed. I am no PDO expert, and I hear you can do some optimization, but it will never be as fast as the old API

  • zaw

    Sweet I’ve been using mysqli since I read your tuts about mysqli. I noticed this PDO for a while but haven’t tried it. Perfect time you did this tuts for me. Thanks for this Jeff :)

  • http://wouterj.nl Wouter J

    “The Correct Way” isn’t or die.

    Nobody dies when it does something wrong, a code also don’t. It is better to use nice error handling on connection, select_db and query.
    An example for MySQL or MySQLi (sorry, the comments are writing in Dutch, but I think you understand the code without comments).

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Did you see where I wrote “anti-pattern” at the top of the code snippet? The tutorial wasn’t about myqsl_connect; it was just a quick example.

  • Abdelaziz

    NIce tut Jeffrey. I’m bookmarking it for the next time someone asks about data access in PHP and what PDO is.

  • http://codexcell.com Murtaza Malek

    Few days ago i have to work on a small task in magento software and i am wondering how those queries were written, after reading this tutorial i came to know it’s PHP PDO. Thanks for the tutorial, it will definitely work like a charm for dummies.
    Thanks a lot.

  • http://kriix.com Kristijan

    Really great tut, I always thought of using PDO because of prepared statements but never found some easy to follow documentation and never took the time to go into details, but now I’m sure I’ll use it, thank you :)

    And only one thing, the part ‘of “Kevin,” and the other, “Steven.”’ made me scroll as I didn’t see any “Kevin” in the code ;)

  • Neil Benson

    I’ve recently used PDO and it is very powerful once you get used to it – however the lack of examples, q&a’s about it and so on can be frustrating. I wish I’d had this tutorial when I started. The only problem I encountered was with prepared statements which run into some limitations with more complex queries.

  • Rüfenacht Michael

    Cool this was finally pointed out at nettuts! One little hint: you perhaps should mention how to start and commit transactions.

  • Levan

    I have a question regarding the last example, about the object mapping. I don’t quite understand where and how the $first_name and $last_name variables get their values? What should the $user->full_name() method print in this case?

  • http://jyggen.com/ Jonas Stendahl

    Actually mysql is deprecated(ish) according to this: http://news.php.net/php.internals/53799.

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Yeah – I link to it in the article.

  • http://varemenos.com/ Varemenos

    can anyone tell me why isnt this working?
    http://pastebin.com/e0BQqJeP

  • Again

    Seriously? Focused on the application? Have you ever put together a real application outside of small code snippets that would be better suited to sitting in the php help docs? Nettuts is seriously going downhill as of late. Stop catering to the “hello world” developers out there.

    Sorry for being such a downer, but between Envato and SmashingMag the quality of posts is dropping and there is a clear change in the intended audience. Time to drop it from the daiy rss feed I think…

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      You’re an angry elf.

      I meant “application” in terms of how to actually use the API. Certainly, for large projects, you’ll want some level of abstraction or active record class. That’s not what this article was about; it was about introducing the extension in a way that’s as easy as possible to understand.

      If you already know this stuff, congrats; don’t read it.

    • Sergey

      Look, even if you think that you are very skilled in something, it is always healthy to get back to basics just in order to make sure you didn’t miss anything;)

      Jeff, thanks for great articles!! It’s always a joy to spend 15 minutes a day on reading an article (even if it is not advanced one) from tuts+! Keep it up.

    • Brian

      You are a pompous douche. Good riddance.

    • Brad

      Out of curiosity, why are you not writing tuts for Nettuts?

    • Nikolai

      Correct.

      I’d love at least to see working example of PDO executing very popular query (if we talk about applications) like this:

      “SELECT name FROM users WHERE id IN(1,2,3,4)”

      Also, it was noted somewhere in comments that you have to cast incoming data as int even if you bind it as PARAM_INT. And that’s no kidding. This is just great. PDO is so awesome – it even lacks some basic functionality.

    • mark prades

      Again , most of the big php orms are based on PDO , so what are you ranting against ? because there are high level librairies , we cant use low level ones ? when you learn a langage , you need to know the basics , because when you have a bug , big libraries/framework wont help you find it. And yes, i use PDO as i wrote my own ORM to fit my needs , which doctrine or propel did not answer ( poor performances , ugly meta configs , etc … )

  • Jesus Bejarano

    OMG Jeffrey, waow i was just trying to connect to my database with the old mysql method and i could not , and then i use this method and vuala all my problems solved. Thank you *U*.

  • mike

    This will make a great reference for me, thanks jdub:)

  • Condimen

    I got a bit confused when you started talking about errors. Where can I learn more about it? I’m decent with HTML and CSS and I think is time i start with PHP and JavaScript.
    By the way, thank you very much for all the articles you write, you’re great!

  • Dan

    I saw that you are using $result->rowCount()… But I once used it and it gave a wrong result back (you can read about it on the original php.net site), I prefer to use count($result->fetchAll()).

    But that on the side, this is a good tutorial, but I think that the choise between MySQLi and PDO is to the user that is building the application (customer). I know that when you change it will be a lot easier with PDO (tough I do not recommend mysql).

  • Brad

    Finally a clear tut that goes a little further than most. Thanks Jeffery

    Someday could you do a tut on using a class and a method, and the different ways to get data from the function to the html page. I currently an stuffing HTML in the function and dont feel comfortable doing it after using Codeigniter

  • maltray

    Wow!, This is amazing.

    I’ve been using PDO for 2 years now, and I never knew about the object mapping that it has…

    THANKS!

  • Alex F

    Excellent tutorial as always Jeffrey.

    I love PDO, but I really miss the ability to use Limit in Updates and Deletes. I know that it is because not all of the supported databases support Limit in these operations, but it just seems like a waste for MySql to go through the entire table when it has already found the one row that I wanted to update.

    Is there any way to implement a limit on Updates and Deletes when accessing MySql with PDO, even if it is a hack?

    Thanks again!

    • http://www.franboud.com Francis Boudreau

      This is a really good question. Is there a workaround for the Limit in Updates and Delete?

  • Tony

    Good read as always Jeff

  • http://rouse.ws William Rouse

    Jeffery:
    Could you give a short example of connecting to a database and using a prepared statement multi-select as in your update example in the tutorial. I cant get one to work and can’t find an example on a web search.
    (one that I understand)
    Thanks!

  • logudotcom

    Good information on PDO. Thank you

  • Custer

    Nice tutorial, very straight-forward. Thanks a lot!

  • Rami

    good tutorial i was using original connection within my class but from now on i will use pdo te best choice

  • Richard Hartmann

    Wow, cool tutorial. I actually really like the way you’re going through this and the way PDO is structured. It reminds me a lot of JPA, which I had to work with all last semester and because of working with it so much, wanted to stick with something similar, so because this is so close, I feel like I’ll actually have to dive into this… Thanks Jeff!!

  • http://n/a Dave, UK

    Hi Jeffrey and thanks for another superb tutorial. As someone who’s only ‘dabbled’ in HTML and CSS in the past, I found your 30 day course to be totally inspiring.

    Your teaching style and enthusiasm to pass on your skills has really pushed me into learning PHP and I look forward to reading much more from you. I’m now experimenting with PDO rather than the older connection methods and I’m starting to see the advantages.

    Keep up the great work and thanks

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Thanks, Dave!

  • http://socialmediadevelopment.org jermaine

    is it ok if i still stick with mysql_connect?

  • http://inkwell.dotink.org Matthew J. Sahagian

    I don’t particularly like how prepared statements are presented, as if they are simply an alternative and better option for escaping data. Prepared statements have many benefits and many limitations. Depending on circumstances they can both increase and decrease performance. Understanding the nature of a prepared statement for what it is, and not just a way to parametize SQL queries and protect against SQL injection, is very important.

    • http://inkwell.dotink.org Matthew J. Sahagian

      I should add, other than that good article. I also was not aware of PDO’s object mapping ability, although it’d be nicer in my opinion if those members were protected and the object had to extend a PDO base class, or better yet, if it had to implement an interface for setters and getters and used private members.

  • Sunny

    I’ve been migrating many years worth of MySQL code over to PDO lately and while the experience has been by-and-large a good and progressive one, there are still some things that PDO requires hacks for or it simply does not support. For example, you can’t have a bound parameter insert a NULL value to clear a field, and you have to use a hack to get the number of rows returned in a SELECT (a seemingly basic feature). PDO is excellent for code portability, but if you’re not going to use a non-MySQL database, it is not always the best option.

  • Vojtěch Dobeš

    While PDO is definitely better then mysql_* set of functions, it’s definitely possible to go further :). I have experienced 2 libraries from this chart (http://sql-cross-queries.freexit.eu/), that remain pretty close to simple DBAL (that PDO is), but bring a lot of goodies. For example Nette\Database directly extends PDO.Dibi can work with much more types of databases, PDO can be picked as one of possible drivers. Definitely worth a look.

  • Ed

    Any thoughts on PDO support for MSSQL?

    When I try this on my MSSQL server, I get a “could not find driver” error message.

  • Aladin

    Thank you, nice work Jeffrey but truly

    $stmt->execute(array(
    ‘:name’ => ‘Justin Bieber’
    ));

    This is the only name you found to do an example?
    It cut the appetite to continue reading…

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      The greatest artist who ever lived?

  • Don

    When using Mysql old api – I connect to the database in a file and include it on all the pages. This means that I don’t have to supply $conn on every query I run and if datbase username or password changes, i know where to make changes quickly.

    If I use PDO in the same way (i.e. connecting in a common include file) – I suppose I have to be careful not to overwrite variable $conn (by mistake) then? as I can see above it needs $conn connection handler to run the queries.

    What is the best method?

    Thanks

  • avisek

    please post an article explaining pinterest like layout engine development without the shifting of floated divs
    on height increment. I need this urgently for my project.

    Thanks.