PHP Forms & Database Integration
CMU529: Advanced Web Development - Session 6
Birmingham Newman University
Lecturer: James Williams
Connecting forms to databases with MySQL
3-hour session • 25 slides • 2 interactive tasks
Session Timeline:
- 10 min: Registration & waiting
- 20 min: Opening slides
- 45 min: Task 1
- 15 min: Break/Catch up
- 20 min: Secondary slides
- 45 min: Task 2
- Remaining: Self-study
Learning Objectives
- Connect PHP forms to MySQL databases
- Implement secure database operations
- Handle form data with database storage
- Create user registration and login systems
- Build data-driven web applications
Database Connection
Basic Database Connection:
<?php
// Database configuration
$host = "localhost";
$username = "root";
$password = "";
$database = "ecommerce";
// Create connection
try {
$pdo = new PDO("mysql:host=$host;dbname=$database", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
?>
- PDO provides database abstraction
- Exception handling for errors
- Secure connection management
Prepared Statements
Secure Database Queries:
// User registration with prepared statement
$stmt = $pdo->prepare("INSERT INTO users (username, email, password) VALUES (?, ?, ?)");
$username = $_POST['username'];
$email = $_POST['email'];
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
try {
$stmt->execute([$username, $email, $password]);
echo "User registered successfully";
} catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
- Prevents SQL injection attacks
- Separates data from SQL logic
- Improves performance with repeated queries
User Authentication
Login Verification:
function authenticateUser($email, $password) {
global $pdo;
$stmt = $pdo->prepare("SELECT id, username, password FROM users WHERE email = ?");
$stmt->execute([$email]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
return true;
}
return false;
}
- Password hashing with password_hash()
- Session management for user state
- Secure credential verification
Form Processing
Complete Registration Process:
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$errors = validateRegistration($_POST);
if (empty($errors)) {
try {
$stmt = $pdo->prepare("INSERT INTO users (username, email, password, created_at) VALUES (?, ?, ?, NOW())");
$hashedPassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
$stmt->execute([$_POST['username'], $_POST['email'], $hashedPassword]);
echo "Registration successful!";
} catch(PDOException $e) {
$errors[] = "Registration failed: " . $e->getMessage();
}
}
}
- Validate input before database operations
- Handle database errors gracefully
- Provide user-friendly feedback
CRUD Operations
Create, Read, Update, Delete:
// CREATE - Insert new product
$stmt = $pdo->prepare("INSERT INTO products (name, price, description) VALUES (?, ?, ?)");
$stmt->execute([$name, $price, $description]);
// READ - Get all products
$stmt = $pdo->query("SELECT * FROM products ORDER BY name");
$products = $stmt->fetchAll();
// UPDATE - Modify product
$stmt = $pdo->prepare("UPDATE products SET price = ? WHERE id = ?");
$stmt->execute([$newPrice, $productId]);
// DELETE - Remove product
$stmt = $pdo->prepare("DELETE FROM products WHERE id = ?");
$stmt->execute([$productId]);
- Always use prepared statements
- Validate data before operations
- Handle errors with try-catch
Data Validation
Database-Level Validation:
function checkEmailExists($email) {
global $pdo;
$stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE email = ?");
$stmt->execute([$email]);
return $stmt->fetchColumn() > 0;
}
function validateUniqueUsername($username) {
global $pdo;
$stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE username = ?");
$stmt->execute([$username]);
return $stmt->fetchColumn() == 0;
}
- Check for duplicate data
- Validate data integrity
- Prevent database conflicts
Session Management
User Session Handling:
session_start();
// Check if user is logged in
function isLoggedIn() {
return isset($_SESSION['user_id']);
}
// Logout function
function logout() {
session_destroy();
header("Location: login.php");
exit();
}
// Protect pages
if (!isLoggedIn()) {
header("Location: login.php");
exit();
}
- Maintain user state across requests
- Secure session management
- Protect restricted pages
Error Handling
Database Error Management:
try {
$stmt = $pdo->prepare("INSERT INTO orders (user_id, total) VALUES (?, ?)");
$stmt->execute([$userId, $total]);
$orderId = $pdo->lastInsertId();
// Insert order items
foreach ($items as $item) {
$stmt = $pdo->prepare("INSERT INTO order_items (order_id, product_id, quantity) VALUES (?, ?, ?)");
$stmt->execute([$orderId, $item['id'], $item['quantity']]);
}
$pdo->commit();
echo "Order placed successfully";
} catch(PDOException $e) {
$pdo->rollback();
error_log("Database error: " . $e->getMessage());
echo "Order failed. Please try again.";
}
- Use try-catch for database operations
- Log errors for debugging
- Provide user-friendly messages
Task 1: User Registration System
Instructions:
- Create a complete user registration system with:
- User registration form with validation
- Database connection using PDO
- Prepared statements for security
- Password hashing implementation
- Email and username uniqueness check
- Error handling and display
- Implement login functionality
- Add session management
- Create password reset functionality
- Test all security measures
Time: 45 minutes
This task will help you master database integration techniques
Break Time
15 Minutes
Take a break, ask questions, or catch up on the previous task.
Next: Secondary slides and Task 2
Database Schema
Users Table:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Products Table:
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL,
stock INT DEFAULT 0,
image VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Product Management
Product Listing with Search:
<?php
// Pagination
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$limit = 12;
$offset = ($page - 1) * $limit;
// Search functionality
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
// Build query
$where = "WHERE 1=1";
$params = [];
if (!empty($search)) {
$where .= " AND (name LIKE ? OR description LIKE ?)";
$params[] = "%$search%";
$params[] = "%$search%";
}
// Get products
$stmt = $pdo->prepare("SELECT * FROM products $where ORDER BY created_at DESC LIMIT ? OFFSET ?");
$params[] = $limit;
$params[] = $offset;
$stmt->execute($params);
$products = $stmt->fetchAll();
?>
File Upload
Image Upload Handling:
function handleImageUpload($file) {
$uploadDir = "uploads/";
$errors = [];
// Check if file was uploaded
if ($file["error"] !== UPLOAD_ERR_OK) {
$errors[] = "File upload failed";
return $errors;
}
// Validate file type
$allowedTypes = ["image/jpeg", "image/png", "image/gif"];
if (!in_array($file["type"], $allowedTypes)) {
$errors[] = "Invalid file type";
}
// Validate file size (2MB max)
if ($file["size"] > 2 * 1024 * 1024) {
$errors[] = "File too large (max 2MB)";
}
// Generate unique filename
$extension = pathinfo($file["name"], PATHINFO_EXTENSION);
$filename = uniqid() . "." . $extension;
$filepath = $uploadDir . $filename;
// Move uploaded file
if (!move_uploaded_file($file["tmp_name"], $filepath)) {
$errors[] = "Failed to save file";
}
return $errors;
}
Shopping Cart
Cart Database Tables:
CREATE TABLE cart (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
product_id INT,
quantity INT DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
total DECIMAL(10,2),
status ENUM('pending', 'processing', 'shipped', 'delivered') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
Performance Optimization
Database Indexes:
// Add indexes for better performance
CREATE INDEX idx_products_name ON products(name);
CREATE INDEX idx_products_price ON products(price);
CREATE INDEX idx_users_email ON users(email);
// Optimized query with joins
$stmt = $pdo->prepare("SELECT p.*, c.name as category_name FROM products p LEFT JOIN categories c ON p.category_id = c.id WHERE p.name LIKE ? ORDER BY p.created_at DESC LIMIT ? OFFSET ?");
- Use indexes on frequently searched columns
- Implement pagination for large datasets
- Optimize image sizes and formats
- Use lazy loading for images
Security Best Practices
Security Implementation:
// Secure password hashing
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// Input sanitization
$username = htmlspecialchars(trim($_POST['username']));
$email = filter_var(trim($_POST['email']), FILTER_SANITIZE_EMAIL);
// CSRF protection
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('CSRF token validation failed');
}
- Always use prepared statements
- Hash passwords with password_hash()
- Validate and sanitize all input
- Use HTTPS in production
Error Logging
Custom Error Handler:
function customErrorHandler($errno, $errstr, $errfile, $errline) {
$errorMessage = date('Y-m-d H:i:s') . " Error: [$errno] $errstr in $errfile on line $errline\n";
error_log($errorMessage, 3, "logs/error.log");
return true;
}
set_error_handler("customErrorHandler");
// Database error handling
try {
$stmt = $pdo->prepare("INSERT INTO products (name, price) VALUES (?, ?)");
$stmt->execute([$name, $price]);
} catch(PDOException $e) {
error_log("Database error: " . $e->getMessage());
echo "An error occurred. Please try again.";
}
Testing & Debugging
Debug Functions:
// Debug function
function debug($data) {
echo "<pre>";
print_r($data);
echo "</pre>";
}
// Test database connection
function testConnection() {
global $pdo;
try {
$stmt = $pdo->query("SELECT 1");
echo "Database connection successful";
} catch(PDOException $e) {
echo "Database connection failed: " . $e->getMessage();
}
}
// Validate form data
function validateProductData($data) {
$errors = [];
if (empty($data['name'])) $errors[] = "Product name is required";
if (!is_numeric($data['price']) || $data['price'] <= 0) $errors[] = "Valid price is required";
return $errors;
}
Task 2: Complete E-commerce System
Instructions:
- Build a complete e-commerce system with:
- User registration and login forms
- Product management (CRUD operations)
- Shopping cart functionality
- Order processing system
- File upload for product images
- Search and filter functionality
- Implement comprehensive validation
- Add security measures (CSRF, input sanitization)
- Include error handling and logging
- Add pagination for product listings
- Test all database operations
Time: 45 minutes
This task will help you build a complete e-commerce database system
Session Summary
- Database integration is essential for dynamic web applications
- Prepared statements prevent SQL injection attacks
- Password hashing protects user credentials
- Session management maintains user state
- Error handling improves application reliability
- Performance optimization enhances user experience
- Security best practices protect against vulnerabilities
- Testing and debugging ensure code quality
Next Session:
Advanced PHP Features - Object-oriented programming and advanced techniques