Database Connectivity 4 programs with output 15 Q/A 5 MCQs

Learning Objectives – after this chapter you will be able to:

  • Explain what ODBC is and when it is useful in PHP.
  • Create an ODBC data source name (DSN) on Windows for MS Access, Oracle or MySQL/MariaDB.
  • Enable the ODBC extension in XAMPP.
  • Connect, run queries and read results with odbc_connect(), odbc_exec(), odbc_fetch_row(), odbc_result() and odbc_close().
  • Use prepared ODBC statements and display data in an HTML table.
What is ODBC?

ODBC (Open Database Connectivity) is a standard programming interface for accessing database management systems. An application talks to the ODBC Driver Manager, which loads the driver for the particular database. With an ODBC connection you can connect to any database, on any computer in your network, as long as an ODBC driver and connection are available – Microsoft Access, Microsoft SQL Server, Oracle, MySQL/MariaDB, PostgreSQL, Excel files and many more.

PHP script Calls odbc_connect("DSN", user, password), odbc_exec(), odbc_fetch_row() …
↓
ODBC extension PHP's odbc extension passes the calls to the operating system.
↓
Driver Manager Windows ODBC Data Source Administrator (or unixODBC on Linux) looks up the DSN.
↓
ODBC driver e.g. Microsoft Access Driver, Microsoft ODBC for Oracle, MariaDB/MySQL Connector/ODBC.
↓
Database Access .accdb/.mdb file, Oracle, SQL Server, MariaDB …

Figure 37.1 – How PHP reaches a database through ODBC

A DSN (Data Source Name) is a named configuration that stores which driver to use and where the database is. The PHP program only needs the DSN name.

ODBC or MySQLi?

For MySQL/MariaDB always use MySQLi (Chapters 34–36) – it is faster and supports all features. ODBC is useful when PHP must read data from a database that has no native PHP extension, for example an existing MS Access file or a legacy system.

Enabling ODBC in XAMPP

The ODBC extension is part of PHP for Windows. If function_exists('odbc_connect') returns false, open Config → PHP (php.ini) in the XAMPP Control Panel, make sure the following line is not commented out (no ; at the beginning) and restart Apache:

C:\xampp\php\php.ini
extension=odbc
Creating an ODBC Connection on Windows
To an MS Access database
  1. Open Control Panel → Administrative Tools (Windows 10/11: Windows Tools), or search the Start menu for "ODBC Data Sources (64-bit)".
  2. Choose the System DSN tab (a system DSN is visible to all users and to the Apache service).
  3. Click Add.
  4. Select Microsoft Access Driver (\.mdb, \.accdb) and click Finish.
  5. In the next screen click Select to locate the database file.
  6. Give the database a Data Source Name (DSN), e.g. northwind.
  7. Click OK.

The bitness must match: 64-bit XAMPP/PHP needs a 64-bit ODBC driver and the 64-bit ODBC administrator. If the 64-bit Access driver is missing, install the free Microsoft Access Database Engine Redistributable (64-bit).

To an Oracle database
  1. Open the ODBC Data Sources administrator.
  2. Choose the System DSN tab and click Add.
  3. Select the Oracle ODBC driver (in older Windows versions Microsoft ODBC for Oracle) and click Finish.
  4. Give the database a Data Source Name (DSN), e.g. oraphp, and the Oracle service name.
  5. Click OK.
To a MySQL or MariaDB database

Install MySQL Connector/ODBC or MariaDB Connector/ODBC, then add a System DSN with the driver MariaDB ODBC … Driver (or MySQL ODBC … Driver), server localhost, user root and the database name.

The DSN used for the outputs in this chapter

The programs in this chapter were run against a DSN named northwind that points (through MariaDB Connector/ODBC and unixODBC on Linux) to a MariaDB copy of the classic Northwind customers table:

/etc/odbc.ini on the Linux test server (the Windows administrator stores the same settings)
[northwind]
Description=Northwind sample database (MariaDB)
Driver=MariaDB Unicode
Server=localhost
Database=northwind
SQL SESSION SQL typed in the MariaDB monitor (XAMPP Shell → mysql -u root) or the phpMyAdmin SQL tab
MariaDB [northwind]> SELECT CustomerID, CompanyName, ContactName, City FROM customers;
+------------+--------------------------+------------------+-------------+
| CustomerID | CompanyName              | ContactName      | City        |
+------------+--------------------------+------------------+-------------+
| ALFKI      | Alfreds Futterkiste      | Maria Anders     | Berlin      |
| ANATR      | Ana Trujillo Emparedados | Ana Trujillo     | Mexico D.F. |
| BHOPL      | Bhopal Book House        | Ramesh Gupta     | Bhopal      |
| BONAP      | Bon app                  | Laurence Lebihan | Marseille   |
| INDOR      | Indore Traders           | Sushma Jain      | Indore      |
+------------+--------------------------+------------------+-------------+
5 rows in set
Connecting to an ODBC Data Source

odbc_connect() connects to an ODBC data source. It takes four parameters: the data source name, user name, password and an optional cursor type. It returns a connection resource (or false). odbc_exec() executes an SQL statement and returns a result identifier.

The classic example connects to an MS Access DSN called northwind with no user name and no password (Access files need none), then creates and executes an SQL statement:

MS Access DSN (Windows)
$conn = odbc_connect('northwind', '', '');
$sql  = "SELECT * FROM customers";
$rs   = odbc_exec($conn, $sql);

For an Oracle DSN called oraphp with the user "system" and password "Manager":

Oracle DSN
$conn = odbc_connect('oraphp', 'system', 'Manager');
$sql  = "SELECT * FROM customers";
$rs   = odbc_exec($conn, $sql);

Our northwind DSN points to MariaDB, which needs a database user, so the programs pass root and the empty XAMPP password:

File: htdocs/phpbook/ch37/connect.php
<?php
$conn = odbc_connect('northwind', 'root', '');
if (!$conn) {
    exit("Connection Failed: " . odbc_errormsg());
}
echo "Connected to the ODBC data source 'northwind'.<br>";
$rs = odbc_exec($conn, "SELECT COUNT(*) AS total FROM customers");
odbc_fetch_row($rs);
echo "Number of customers: " . odbc_result($rs, "total");
odbc_close($conn);
?>
OUTPUT browser · http://localhost/phpbook/ch37/connect.php
Connected to the ODBC data source 'northwind'.
Number of customers: 5
Retrieving Records

odbc_fetch_row() moves to the next record of the result set. It returns true if it was able to return a row, otherwise false. It takes two parameters: the ODBC result identifier and an optional row number.

odbc_fetch_row($rs)
Retrieving fields from a record

odbc_result() reads a field from the current record. It takes two parameters: the ODBC result identifier and a field number or name. The line below returns the value of the first field:

$compname = odbc_result($rs, 1);

and this line returns the value of the field called CompanyName:

$compname = odbc_result($rs, "CompanyName");
Closing an ODBC connection

odbc_close() closes an ODBC connection:

odbc_close($conn);
An ODBC Example

The following example first creates a database connection, then a result set, and then displays the data in an HTML table:

File: htdocs/phpbook/ch37/customers.php
<html>
<body style="font-family:Arial;font-size:13px">
<?php
$conn = odbc_connect('northwind', 'root', '');
if (!$conn) {
    exit("Connection Failed: " . $conn);
}
$sql = "SELECT * FROM customers";
$rs = odbc_exec($conn, $sql);
if (!$rs) {
    exit("Error in SQL");
}
echo "<table border='1' cellpadding='4' style='border-collapse:collapse'><tr>";
echo "<th>Companyname</th>";
echo "<th>Contactname</th></tr>";
while (odbc_fetch_row($rs)) {
    $compname = odbc_result($rs, "CompanyName");
    $conname = odbc_result($rs, "ContactName");
    echo "<tr><td>$compname</td>";
    echo "<td>$conname</td></tr>";
}
odbc_close($conn);
echo "</table>";
?>
</body>
</html>
OUTPUT browser · http://localhost/phpbook/ch37/customers.php
Browser output
More ODBC Functions
FunctionPurpose
odbc_connect(dsn, user, password [, cursor])Connects to a data source.
odbc_pconnect(...)Opens a persistent connection.
odbc_exec(conn, sql)Prepares and executes an SQL statement. odbc_do() is an alias.
odbc_prepare(conn, sql) / odbc_execute(result, params)Prepares a statement with ? placeholders / executes it with an array of values.
odbc_fetch_row(result [, row])Fetches the next (or given) row.
odbc_fetch_array(result) / odbc_fetch_object(result)Fetches a row as an associative array / object.
odbc_result(result, field)Gets the value of a field of the current row (by number or name).
odbc_result_all(result)Printed a result as an HTML table – deprecated in PHP 8.1.
odbc_num_rows(result) / odbc_num_fields(result)Number of rows (for UPDATE/INSERT/DELETE; many drivers return -1 for SELECT) / columns.
odbc_field_name(result, n) / odbc_field_type(result, n)Name / type of a column.
odbc_tables(conn) / odbc_columns(conn, …)Lists tables / columns of the data source.
odbc_autocommit / odbc_commit / odbc_rollback (conn)Transaction control.
odbc_error(conn) / odbc_errormsg(conn)Last SQLSTATE error code / message.
odbc_close(conn) / odbc_close_all()Closes a connection / all connections.
Prepared statements and fetch_array
File: htdocs/phpbook/ch37/prepared.php
<?php
$conn = odbc_connect('northwind', 'root', '');
$stmt = odbc_prepare($conn, "SELECT CustomerID, CompanyName, City FROM customers WHERE Country = ?");
odbc_execute($stmt, [$_GET['country'] ?? 'India']);
echo "Columns: " . odbc_num_fields($stmt) . " (";
for ($i = 1; $i <= odbc_num_fields($stmt); $i++) {
    echo odbc_field_name($stmt, $i) . ($i < odbc_num_fields($stmt) ? ", " : "");
}
echo ")<br>";
while ($row = odbc_fetch_array($stmt)) {
    echo htmlspecialchars("{$row['CustomerID']}: {$row['CompanyName']} – {$row['City']}") . "<br>";
}
odbc_close($conn);
?>
OUTPUT browser · http://localhost/phpbook/ch37/prepared.php?country=India
Columns: 3 (CustomerID, CompanyName, City)
BHOPL: Bhopal Book House – Bhopal
INDOR: Indore Traders – Indore
Handling ODBC errors
File: htdocs/phpbook/ch37/odbcerror.php
<?php
$conn = odbc_connect('northwind', 'root', '');
$rs = @odbc_exec($conn, "SELECT * FROM suppliers");      // table does not exist
if (!$rs) {
    echo "SQLSTATE: " . odbc_error($conn) . "<br>";
    echo "Message: " . odbc_errormsg($conn);
}
odbc_close($conn);
?>
OUTPUT browser · http://localhost/phpbook/ch37/odbcerror.php
SQLSTATE: S0002
Message: [ma-3.1.15][10.11.14-MariaDB-0ubuntu0.24.04.1]Table 'northwind.suppliers' doesn't exist
Key Takeaways
  • ODBC is a standard interface that lets PHP reach any database for which an ODBC driver exists.
  • A DSN (Data Source Name) stores the driver and the location of the database; create a System DSN in the ODBC Data Source Administrator.
  • Enable extension=odbc in php.ini; match 32/64-bit drivers with PHP.
  • odbc_connect(dsn, user, password) → odbc_exec(conn, sql) → odbc_fetch_row() + odbc_result() → odbc_close().
  • odbc_prepare()/odbc_execute() give prepared statements; odbc_errormsg() reports errors.
  • For MySQL/MariaDB itself prefer MySQLi.
Program File

Extract the ZIP into C:\xampp\htdocs. It creates the folder phpbook/ch37 used in the file labels above; open the programs at http://localhost/phpbook/… with Apache (and MySQL, where needed) started in the XAMPP Control Panel.

Question / Answer (15 questions)

Answer : Open Database Connectivity – a standard API through which an application can access many different database systems using database-specific drivers loaded by an ODBC driver manager.

Answer : A Data Source Name – a named configuration that tells the ODBC driver manager which driver to use and where the database is (file, server, database name, options).

Answer : A User DSN is visible only to the Windows user who created it; a System DSN is visible to all users and to services such as Apache, so PHP applications normally need a System DSN.

Answer : Open ODBC Data Sources (Administrative Tools), choose the System DSN tab, click Add, select the Microsoft Access Driver and click Finish, click Select to locate the database, give a DSN name and click OK.

Answer : Remove the semicolon before extension=odbc in C:\xampp\php\php.ini and restart Apache.

Answer : The data source name, the user name, the password and an optional cursor type; it returns a connection resource or false.

Answer : It executes an SQL statement on an ODBC connection and returns a result identifier (or false on error).

Answer : true if it could move to the next row of the result, false when there are no more rows; it takes the result identifier and an optional row number.

Answer : odbc_result($rs, 1) reads the first field of the current row; odbc_result($rs, "CompanyName") reads the field by name.

Answer : while (odbc_fetch_row($rs)) { $name = odbc_result($rs, "CompanyName"); echo $name . "<br>"; }

Answer : With odbc_close($conn), or odbc_close_all() for all connections.

Answer : $stmt = odbc_prepare($conn, "SELECT … WHERE Country = ?"); odbc_execute($stmt, [$country]); then fetch rows from $stmt.

Answer : odbc_error($conn) returns the SQLSTATE code, and odbc_errormsg($conn) returns the error message of the last failed operation.

Answer : A 64-bit PHP process can only load 64-bit ODBC drivers (and 32-bit only 32-bit drivers); a mismatch results in "data source name not found" errors.

Answer : When the database has no native PHP extension or must be accessed through an existing ODBC setup – for example an MS Access file or a legacy database. For MySQL/MariaDB, MySQLi is preferred.
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. ODBC stands for:

Show Answer

Correct Answer : B. Open Database Connectivity
It is a standard database API.

Q2. Which DSN type is visible to Apache running as a service?

Show Answer

Correct Answer : C. System DSN
System DSNs are available to all users and services.

Q3. Which function moves to the next row of an ODBC result?

Show Answer

Correct Answer : B. odbc_fetch_row()
It returns true while rows remain.

Q4. odbc_result($rs, "CompanyName") returns:

Show Answer

Correct Answer : B. The value of the CompanyName field of the current row
Fields can be read by name or number.

Q5. Which php.ini line enables ODBC?

Show Answer

Correct Answer : A. extension=odbc
Remove the semicolon before extension=odbc.

Bibliography/References

The notes on this page are the author’s own compilation from the e-book PHP: Basics to Advance. Every program was run on Apache with PHP 8 and MariaDB, and the output shown is the real result of that run. The works listed below were consulted and are cited for attribution and further reading. Product names and trademarks belong to their respective owners.

  1. The PHP Group. (n.d.). PHP Manual – ODBC Functions (Unified). https://www.php.net/manual/en/ref.uodbc.php
  2. The PHP Group. (n.d.). PHP Manual – odbc_connect. https://www.php.net/manual/en/function.odbc-connect.php
  3. Microsoft. (n.d.). ODBC Data Source Administrator. Microsoft Learn. https://learn.microsoft.com/en-us/sql/odbc/admin/odbc-data-source-administrator
  4. MariaDB plc. (n.d.). MariaDB Connector/ODBC. https://mariadb.com/kb/en/mariadb-connector-odbc/
  5. unixODBC Project. (n.d.). unixODBC. https://www.unixodbc.org/