Wednesday 11 July 2018

MYSQL VS MYSQLI VS PDO

Overview

To understand the difference between MySQL, MySQLi and PDO first we need to understand all of it individually.
There are two or three PHP APIs for accessing the MySQL database depending on PHP version. The user who uses PHP 5, they can choose MySQL which is deprecated, Mysqli or PDO. The user who uses PHP 7, they have only two options either MySQL or PDO.

MySQL

This is the main original extension designed to develop PHP applications that interact with a MySQL database. It provides procedural interface but it is deprecated as of PHP 5.5.0 and has been removed as of PHP 7.0.0. So, I suggest to use either MySQLi or PDO extension.

MySQLi

The i stands for Improved. The MySQLi is an extension to work with MySQL version 4.1.13 or newer. MySQLi is introduced with PHP Version 5.0 and MySQLi takes advantage of the newer features of MySQL 5.

PDO

PDO stands for PHP Data Objects. It is a database access layer providing a uniform method of access to multiple databases. PDO supports twelve different databases which are as below:
  1. CUBRID
  2. MS SQL Server
  3. Firebird/Interbase
  4. IBM
  5. Informix
  6. MySQL
  7. Oracle
  8. ODBC and DB2
  9. PostgreSQL
  10. SQLite
  11. 4D
PDO sadly has one disadvantage, it does not allow you to use all of the advanced features that are available in the latest versions of MySQL server. Consider example, PDO does not allow you to use MySQL’s support for Multiple Statements.

Difference between MySQL, MySQLi and PDO

The main differences of three extensions are as below.
MySQLMySQLiPDO
Introduced with PHP version2.05.05.1
Development statusMaintenance only in 5.x; removed in 7.xYesYes
LifecycleDeprecated in 5.x; Removed in 7.xActiveActive
Recommended for new projectsNoYesYes
OOP InterfaceNoYesYes
Procedural InterfaceYesYesNo
API supports non-blocking, asynchronous queries with mysqlndNoYesNo
Persistent ConnectionsYesYesYes
API supports CharsetsYesYesYes
API supports server-side Prepared StatementNoYesYes
API supports client-side Prepared StatementNoNoYes
API supports Stored ProceduresNoYesYes
API supports Multiple StatementsNoYesMost
API supports TransactionsNoYesYes
Transaction can be controlled with SQLYesYesYes
Supports all MySQL 5.1+ functionalityNoYesMost
Now, let’s discuss some functional differences of above three extensions.

Connection to MySQL database

In MySQL function we can connect to the database by following code:
In MySQLi to create a connection just instantiating a new instance of MySQLi and using a username with a password connecting to the database, as follow:
In PDO We need to create a new PDO object. The constructor accepts four parameters for specifying the database source which are DSN (data source name) and optionally username, password. DSN is basically a string of options of driver to use and connection details of database.
You can pass fourth parameter as of several driver options as an array. Some PDO drivers do not support native prepared statements, so I recommend pass the parameter which put PDO into exception mode, so PDO performs emulation of the prepare. You can also manually enable this emulation. To use the native server-side prepared statements, you should explicitly set it false. Prepare emulation should be turned off to use PDO safely.
It will throw PDOException object if there is any connection error, we can catch it to handle Exception. So we can set attributes after PDO construction with the setAttribute method:

Error Handling

In MySQL

We cannot handle the thing in die but die is not a good approach to handle error. Die will end the script abruptly and then echo the error to the screen which you usually don’t want to show to your users, and let hackers to discover your schema.

In MySQLi

mysqli::$error – mysqli_error : Returns a string description of the last error.

In PDO

In PDO a better solution is exceptions. Anything in PDO should be wrapped in a try-catch block. Also we can force PDO into error mode by setting the error mode attribute from following error modes.
PDO::ERRMODE_SILENT: By setting this error code you must check each result then check $db->errorInfo() to get error details.
PDO::ERRMODE_WARNING: It provides Run-time warnings (E_WARNING) not fatal errors. It’s execution does not halt the script.
PDO::ERRMODE_EXCEPTION: It throw exceptions that shows an error raised by PDO. You should not throw a PDOException with your own code. It acts much like or die(mysql_error()), when it isn’t caught. But we can catch these PDOException and handle as we want.
We can set these error modes as follow:
You can add a try/catch block as like below:
You can set a user friendly error message instead of exception message. You should use try/catch block for your PDO part also you can use it outside the function that has the PDO functions.

Fetching Data from database

In MySQL

Using loop on results the username for each row will be the out as following:

In MySQLIi

Using loop on results the username for each row will be the out as following:

In PDO

PDOStatement::fetchAll() – Returns an array containing all of the resultset rows PDOStatement::fetchColumn() – Returns a single column from the next row of a resultset. PDOStatement::fetchObject() – Fetches the next row and returns it as an object. PDOStatement::setFetchMode() – Set the default fetch mode for this statement
query() returns a PDOStatement object by that you can fetch the data directly by using foreach and for loop also.

Getting the Row Count

Instead of using mysql_num_rows() in MySQL and mysqli_num_rows() or $my_result->num_rows in MySQLi to get the number of returned rows, you can get a PDOStatement and do rowcount, like:

Update statements

We use mysql_affected_rows() in MySQL and mysqli_affected_rows() or $my_result->affected_rows in MySQLi.  In PDO, we can do the same by:
There are some functionalities that are not supported by MySQL and supported by remaining both MySQLi and PDO.

Prepared Statements

A prepared statement is a precompiled SQL statement that can be executed multiple times by sending the data to the server.
The flow of the prepared statement is as follows:
  1. Prepare: The statement template is created by the application and sent to the DBMS. Some parameters are left unspecified by placeholders “?” like as below:
  2. Bind: The DBMS parses, compiles, and performs query optimization on statement template and stores the result without executing it.
  3. Execute: The application binds values for the parameters and the DBMS executes the statement. The application may execute the statement as many times as it wants with different values.
Named placeholders: You can use a descriptive names preceded by a colon, instead of question marks. We don’t care about position or order of value in named placeholder:
Unnamed placeholders: In unnamed placeholders we must follow the proper order of the elements.

In MySQLi

In PDO

API Support

Both PDO and MySQLi provides an object-oriented approach, but MySQLi provides a procedural way also like old mysql extension. New users may prefer MySQLi because of procedural interface which is similar to old mysql extension, So migrating from the old mysql extension is easier. But after mastering in PDO, you can use it with any database you like.

Security

Both PDO and MySQLi provide SQL injection security, as long as developers follow them with features like escaping and parameter binding with prepared statements.
For example a hacker is trying to inject some malicious SQL through the ‘name’ HTTP query parameter (POST):
If we fail to escape, it will be added in query “as it is”, it will delete all rows from users table as PDO and MySQLi support multiple queries.
In PDO, “manual” escaping
In MySQLi, “manual” escaping
PDO::quote() not only escapes the string, but it also quotes it. But mysqli_real_escape_string() will only escape the string, you will need to apply the quotes manually.

Conclusion

There are only two possibilities to use extension because MySQL is deprecated as of PHP 5.5.0 and removed as of PHP 7.0.0.
  1. MySQLi
  2. PDO
As per my opinion, if there are possibilities to use more than one database drivers or another than MySQL in your project then you can use PDO, otherwise use MySQLi because PDO not support latest functionalities of MySQL.

0 comments:

Post a Comment