Database Integration: MySQL with PHP on Ubuntu 24 Server
A Comprehensive Content Guide for Web Application Development
Table of Contents
Introduction & Architecture Overview
Installing & Configuring MySQL on Ubuntu 24
MySQL Server Administration Essentials
PHP & MySQL Connection Methods
CRUD Operations with PHP & MySQL
Prepared Statements & Parameterized Queries
Database Design & Schema Management
Working with Joins & Complex Queries in PHP
Transactions & Data Integrity
User Authentication with MySQL
Pagination, Search & Filtering
File Uploads & Binary Data Storage
Building a Complete CRUD Application
Troubleshooting Common Issues
1. Introduction & Architecture Overview
What is Database Integration?
Database integration is the process of connecting a web application's front-end and back-end logic to a persistent data storage system. In a typical LAMP stack (Linux, Apache, MySQL, PHP), the architecture follows a clear flow:
Request Lifecycle:
The user's browser sends an HTTP request to the Apache web server.
Apache identifies the request as a PHP file and hands it to the PHP interpreter.
PHP executes the script, which may include SQL queries sent to the MySQL server.
MySQL processes the queries and returns result sets to PHP.
PHP formats the data into HTML (or JSON) and sends it back through Apache.
The browser renders the final response for the user.
MySQL is one of the most widely deployed relational database management systems (RDBMS) in the world. It powers major platforms including WordPress, Facebook, Twitter, and YouTube. Key advantages include open-source licensing, excellent performance, broad hosting support, a mature ecosystem of tools, and strong community documentation.
Ubuntu 24.04 LTS (Noble Numbat) provides long-term support through 2029, making it an ideal production server environment. It ships with modern versions of PHP (8.3+), MySQL (8.0+), and Apache (2.4+), ensuring compatibility with current web development standards and security patches.
PHP's MySQL Extensions: A Brief History
PHP has offered several extensions for MySQL connectivity over the years:
Course Standard: Throughout this guide, we will primarily use MySQLi (object-oriented) for direct MySQL work and introduce PDO for comparison. Both are industry-standard approaches.
2. Installing & Configuring MySQL on Ubuntu 24
Step 1: Update the System
Always begin by updating the package lists and upgrading installed packages:
Step 2: Install MySQL Server
Verify the installation and check the running version:
Step 3: Secure the Installation
MySQL ships with a security script that walks you through hardening the default configuration:
This interactive script will prompt you to:
Set up the VALIDATE PASSWORD component — Choose the password validation policy level (LOW = 8+ chars, MEDIUM = mixed case + numbers + special, STRONG = dictionary checks).
Set/change the root password — Create a strong root password.
Remove anonymous users — Answer Y to prevent unauthenticated access.
Disallow root login remotely — Answer Y for security (root should only connect from localhost).
Remove the test database — Answer Y to delete the default test database.
Reload privilege tables — Answer Y to apply changes immediately.
Step 4: Install PHP and the MySQL Extension
This installs:
php — The PHP interpreter (version 8.3+ on Ubuntu 24).
php-mysql — The MySQLi and PDO MySQL drivers.
php-cli — Command-line PHP for testing scripts without Apache.
libapache2-mod-php — The Apache module that allows PHP processing.
Verify PHP installation:
Verify the MySQL extensions are loaded:
Step 5: Restart Apache
Step 6: Test PHP Processing
Create a test file to verify Apache is processing PHP correctly:
Navigate to http://your-server-ip/info.php in a browser. You should see the PHP information page. Look for sections labeled mysqli and PDO to confirm the database drivers are loaded.
Security Warning: Always delete info.php after testing. It exposes sensitive server configuration details.
By default, the MySQL root user authenticates using auth_socket (OS-level authentication), which means PHP scripts cannot connect as root using a password. You need to either change root's authentication method or (recommended) create a dedicated application user.
Option A: Create a Dedicated Application User (Recommended)
Best Practice: In production, never grant ALL PRIVILEGES on *.*. Instead, grant only the specific permissions needed on specific databases. The above is acceptable only in a development/learning environment.
Option B: Change Root Authentication (Development Only)
Step 8: Verify the Connection from Command Line
3. MySQL Server Administration Essentials
Managing the MySQL Service
The MySQL Configuration File
The primary configuration file is located at /etc/mysql/mysql.conf.d/mysqld.cnf. Key settings to be aware of:
After modifying the configuration file, restart MySQL:
Creating Databases and Users via Command Line
Useful Administrative Commands
MySQL Log Files on Ubuntu 24
4. PHP & MySQL Connection Methods
Method 1: MySQLi (Object-Oriented)
This is the most common method for MySQL-specific applications. The object-oriented syntax is cleaner and preferred over the procedural alternative.
Method 2: MySQLi (Procedural)
The procedural approach uses functions instead of objects. It works identically but is considered less elegant:
Method 3: PDO (PHP Data Objects)
PDO provides a database-agnostic abstraction layer. If you ever switch from MySQL to PostgreSQL or SQLite, your code changes are minimal.
Creating a Reusable Connection File
In real applications, you never duplicate connection code. Create a single configuration file that all scripts include:
config/database.php
Usage in another script:
MySQLi vs. PDO: When to Use Which
5. CRUD Operations with PHP & MySQL
CRUD stands for Create, Read, Update, Delete — the four fundamental operations for any database-driven application.
Setting Up a Sample Database
First, let's create the database schema we'll use throughout these examples:
CREATE — Inserting Data
Simple Insert (MySQLi)
$conn->insert_id returns the auto-generated ID from the most recent INSERT operation. This is essential when you need the new record's ID immediately after creation.
Insert with Prepared Statement (MySQLi) — The Correct Way
Insert with PDO
Notice: PDO supports named placeholders (:first_name) which makes the code more readable than positional ? marks, especially for queries with many parameters.
READ — Retrieving Data
Fetch All Rows
Critical: Always use htmlspecialchars() when outputting database values into HTML. This prevents Cross-Site Scripting (XSS) attacks by converting special characters like <, >, ", and & into their HTML entity equivalents.
Fetch Methods Comparison
Fetch a Single Record by ID
Fetch with PDO
UPDATE — Modifying Data
Important: $stmt->affected_rows returns the number of rows actually changed. If you run an UPDATE with the same values that already exist, affected_rows will be 0 even though the query executed successfully. This is expected behavior.
Update with PDO
DELETE — Removing Data
Soft Delete (Best Practice)
In production applications, records are rarely physically deleted. Instead, use a "soft delete" by setting a flag:
Then modify all SELECT queries to filter:
6. Prepared Statements & Parameterized Queries
Why Prepared Statements Are Non-Negotiable
Prepared statements are the single most important security measure for database-driven applications. They completely prevent SQL injection attacks by separating SQL logic from user-supplied data.
The SQL Injection Problem
Consider this dangerously vulnerable code:
If a malicious user submits the username as admin' --, the query becomes:
The -- is a SQL comment that disables the password check, giving the attacker access to any account.
Even worse, submitting '; DROP TABLE users; -- could destroy your entire table:
The Prepared Statement Solution
With prepared statements, the database engine treats the ? placeholders as data positions, not SQL code. No matter what the user submits, it will always be treated as a literal string value, never as executable SQL.
MySQLi Prepared Statement Lifecycle
Bind Parameter Types Reference
PDO Prepared Statement with Named Parameters
PDO with Explicit Type Binding
Handling Dynamic WHERE Clauses Safely
A common challenge is building queries where the WHERE conditions depend on user input (e.g., a search form with optional filters):
7. Database Design & Schema Management
Data Types Quick Reference
Numeric Types
Rule of Thumb: Use DECIMAL for money and grades (exact precision required). Use FLOAT/DOUBLE only when approximate values are acceptable.
String Types
Date/Time Types
DATETIME vs. TIMESTAMP: TIMESTAMP converts to UTC for storage and back to the server's timezone on retrieval, and supports DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP. DATETIME stores the literal value without timezone conversion.
Indexes dramatically speed up SELECT queries on large tables, but they add overhead to INSERT/UPDATE/DELETE operations (the index must be maintained).
When to add an index:
Columns frequently used in WHERE clauses
Columns used in JOIN conditions
When NOT to index:
Small tables (under a few hundred rows)
Columns with very low cardinality (e.g., a boolean is_active column with only 2 values)
Tables with heavy INSERT/UPDATE/DELETE and rare SELECT
Foreign Keys & Referential Integrity
Foreign keys enforce relationships between tables, preventing orphaned records:
ON DELETE / ON UPDATE Options:
Altering Tables
8. Working with Joins & Complex Queries in PHP
Understanding JOINs Visually
INNER JOIN — Only Matching Rows
Returns only students who are enrolled in at least one course:
Null Coalescing Operator ??: The expression $row['grade'] ?? 'In Progress' returns 'In Progress' if $row['grade'] is NULL. This is a clean PHP 7+ alternative to isset() checks.
LEFT JOIN — All Left Table Rows, Even Without Matches
Returns ALL students, including those not enrolled in any courses:
GROUP_CONCAT() is a powerful MySQL aggregate function that concatenates values from multiple rows into a single string. In this example, it produces output like "CS101, CS301" for a student enrolled in two courses.
Aggregate Queries
9. Transactions & Data Integrity
What Are Transactions?
A transaction groups multiple SQL operations into a single atomic unit. Either ALL operations succeed (COMMIT), or ALL are rolled back (ROLLBACK). This ensures data consistency even if an error occurs mid-operation.
ACID Properties
Transaction Example: Enrolling a Student
Enrolling a student requires multiple operations: checking prerequisites, checking seat availability, inserting the enrollment record, and updating the enrollment count. If any step fails, we need to undo everything.
Transaction with PDO
10. User Authentication with MySQL
Database Schema for Authentication
Registration: Hashing Passwords
Never store plain-text passwords. PHP's password_hash() function uses the bcrypt algorithm by default:
Login: Verifying Passwords
Session-Based Access Control
auth_check.php — Include this at the top of every protected page:
Usage on a protected page:
Admin-only page:
11. Pagination, Search & Filtering
Basic Pagination
Pagination displays a subset of rows per page, preventing the browser from loading thousands of records at once.
Search with Pagination
Combining a search feature with pagination requires passing the search term through pagination links:
12. File Uploads & Binary Data Storage
Approach 1: Store File Path in Database (Recommended)
Store uploaded files on the filesystem and save only the file path in the database. This is more efficient and scalable than storing binary data directly.
Approach 2: Store Binary Data in Database (BLOB)
For small files or when database portability is important:
13. Error Handling & Logging
PHP Error Handling Levels
Configure error reporting in php.ini or at runtime:
MySQLi Error Handling
Custom Error Logger
Try-Catch Pattern for Database Operations
14. Security Best Practices
The Security Checklist
Every database-driven PHP application should implement the following protections:
1. SQL Injection Prevention
Always use prepared statements with parameterized queries. No exceptions.
2. Cross-Site Scripting (XSS) Prevention
Always escape output with htmlspecialchars():
3. Cross-Site Request Forgery (CSRF) Protection
Add CSRF tokens to all forms that modify data:
4. Password Security
5. Database Connection Security
6. Principle of Least Privilege
7. Input Validation & Sanitization
Query Optimization
Use EXPLAIN to Analyze Queries
Key columns in EXPLAIN output:
Index Optimization
PHP Optimization
Connection Pooling with Persistent Connections
Fetch Only What You Need
Use Buffered vs. Unbuffered Queries
Batch Inserts
Caching Strategies
16. Building a Complete CRUD Application
Project Structure
includes/functions.php
includes/header.php
index.php — Student Listing
student_add.php — Add Student
17. Troubleshooting Common Issues
Connection Errors
MySQL Query Errors
Debugging Checklist
Enable error display (development only):
Print the actual SQL being executed:
Check MySQL error output:
Check the MySQL error log:
Test the query directly in MySQL CLI:
Then paste and run the SQL directly to isolate PHP vs. MySQL issues.
Check PHP extension status:
Verify Apache is loading PHP:
Quick Reference Card
MySQLi Connection Template
Prepared Statement Template
PDO Connection Template
Essential Security Functions