PHPDatabases Introduction

Databases Introduction

Almost every real PHP application needs to remember things between requests: user accounts, blog posts, orders, comments. PHP itself has no memory from one page load to the next — each request starts a fresh process that forgets everything once it finishes. A database is what gives an application persistent, shared storage that every request can read from and write to, whether that request comes from the same visitor a minute later or a completely different visitor on the other side of the world. This page is the on-ramp for the rest of the database section: it explains the two extensions PHP ships for talking to a relational database, and why one of them is worth reaching for by default.

Two built-in ways to talk to a database

PHP does not force you to install a third-party library just to run a SQL query. Two extensions are commonly available out of the box (or via a very common PHP extension install):

  • mysqli — "MySQL Improved". Works only with MySQL and MariaDB, offers both a procedural and an object-oriented API.

  • PDO (PHP Data Objects) — a database-agnostic abstraction layer that works with MySQL, PostgreSQL, SQLite, SQL Server, and others through interchangeable drivers.

Both extensions can run plain queries and both support prepared statements, which is the mechanism that keeps user input from being interpreted as SQL code (covered in full on the prepared statements page). The real difference between them is scope and consistency, not security.

Why PDO is the usual default

PDO is generally the recommended starting point for new PHP code, for a few concrete reasons rather than fashion:

  • Database-agnostic — the same PDO object and method calls work against MySQL, PostgreSQL, or SQLite; switching databases mostly means changing the connection string, not rewriting queries.

  • One consistent API->prepare(), ->execute(), and ->fetch() behave the same way regardless of which driver is underneath, so there is less to remember and less that changes if a project ever migrates databases.

  • Native prepared statements — parameter binding is a first-class part of the API, not something bolted on.

  • Flexible error handlingPDO can be configured to throw real exceptions on failure, so database errors fit naturally into normal try/catch code instead of needing to be checked after every call.

mysqli

PDO

Databases supported

MySQL / MariaDB only

MySQL, PostgreSQL, SQLite, SQL Server, and more

API style

Procedural or object-oriented

Object-oriented only

Prepared statements

Yes

Yes

Named placeholders

No

Yes

Typical use today

Legacy MySQL-only codebases

New projects, especially anything that might need portability

How a query actually reaches the database

It helps to picture the layers a query passes through before a row of data ever comes back to your PHP script. Your application code never talks to the database file or server directly — it always goes through an extension and a driver:

Request path for a database query

Text
Your PHP code
      |
      |  $pdo->query('SELECT ...')  or  $pdo->prepare(...)->execute(...)
      v
PDO (or mysqli) extension    <- consistent PHP-facing API
      |
      v
Database driver (pdo_mysql, pdo_pgsql, pdo_sqlite, ...)
      |
      |  translates calls into the database's wire protocol
      v
Database server (MySQL, PostgreSQL, ...) or database file (SQLite)

Because the driver is the layer that actually knows how to speak MySQL's or PostgreSQL's wire protocol, swapping pdo_mysql for pdo_pgsql in the connection string is often the only change needed to move an application's queries onto a different database engine — as long as the SQL itself doesn't rely on syntax that's specific to one vendor.

Connecting with each extension, at a glance

The connection setup for each extension looks different, but they both end with an object you'll call query methods on.

mysqli (object-oriented style)

PHP
<?php
$mysqli = new mysqli('localhost', 'app_user', 'secret', 'shop');

if ($mysqli->connect_errno) {
    die('Connection failed: ' . $mysqli->connect_error);
}

PDO

PHP
<?php
$dsn = 'mysql:host=localhost;dbname=shop;charset=utf8mb4';

try {
    $pdo = new PDO($dsn, 'app_user', 'secret', [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    ]);
} catch (PDOException $e) {
    die('Connection failed: ' . $e->getMessage());
}
A database extension is not a database
`mysqli` and `PDO` are PHP's clients for talking to a database server — they don't store any data themselves. You still need an actual database engine such as MySQL, MariaDB, PostgreSQL, or SQLite installed and running (or a file, for SQLite) for either extension to connect to.
Tip
Unless you're maintaining an existing mysqli codebase or have a specific reason to stay MySQL-only, start new projects with `PDO`. The dedicated pages for mysqli and PDO that follow go through both APIs in detail, and the prepared statements page covers the single most important habit for writing safe database code in either one.