James Williams
Birmingham Newman University
jwilliams@staff.newman.ac.uk
3-hour session
<?php
class User {
private $id;
private $username;
private $email;
public function __construct($username, $email) {
$this->username = $username;
$this->email = $email;
}
public function getUsername() {
return $this->username;
}
}
$user = new User("john_doe", "john@example.com");
echo $user->getUsername(); // Output: john_doe
?>
<?php
namespace App\Models;
class Product {
private $name;
private $price;
public function __construct($name, $price) {
$this->name = $name;
$this->price = $price;
}
}
// Using the class
use App\Models\Product;
$product = new Product("Laptop", 999.99);
?>
<?php
set_error_handler(function($severity, $message, $file, $line) {
throw new ErrorException($message, 0, $severity, $file, $line);
});
try {
$result = 10 / 0;
} catch (ErrorException $e) {
error_log("Error: " . $e->getMessage());
echo "An error occurred. Please try again.";
} finally {
restore_error_handler();
}
?>
<?php
function validateEmail($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL);
}
function sanitizeInput($input) {
$input = trim($input);
$input = stripslashes($input);
$input = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
return $input;
}
$email = sanitizeInput($_POST['email']);
if (validateEmail($email)) {
// Process valid email
}
?>
<?php
// BAD - Vulnerable to SQL injection
$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
// GOOD - Using prepared statements
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);
$user = $stmt->fetch();
// Also good - Using named parameters
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username");
$stmt->execute(['username' => $username]);
?>
<?php
// Prevent XSS attacks
function escapeOutput($data) {
if (is_array($data)) {
return array_map('escapeOutput', $data);
}
return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
}
$userInput = "<script>alert('XSS')</script>";
echo escapeOutput($userInput);
// Output: <script>alert('XSS')</script>
?>
<?php
session_start();
// Generate CSRF token
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// In form
echo '<input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">';
// Verify token
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('CSRF token validation failed');
}
?>
<?php
// Hash password
$password = "user_password";
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// Verify password
if (password_verify($password, $hashedPassword)) {
echo "Password is correct";
}
// Check if password needs rehashing
if (password_needs_rehash($hashedPassword, PASSWORD_DEFAULT)) {
$newHash = password_hash($password, PASSWORD_DEFAULT);
}
?>
<?php
// BAD - N+1 query problem
$users = $pdo->query("SELECT * FROM users")->fetchAll();
foreach ($users as $user) {
$orders = $pdo->query("SELECT * FROM orders WHERE user_id = " . $user['id']);
}
// GOOD - Single query with JOIN
$stmt = $pdo->query("SELECT u.*, o.* FROM users u LEFT JOIN orders o ON u.id = o.user_id");
$results = $stmt->fetchAll();
// Use indexes
// CREATE INDEX idx_user_email ON users(email);
?>
<?php
// Simple file caching
function getCachedData($key, $callback, $ttl = 3600) {
$cacheFile = "cache/" . md5($key) . ".cache";
if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < $ttl) {
return unserialize(file_get_contents($cacheFile));
}
$data = $callback();
file_put_contents($cacheFile, serialize($data));
return $data;
}
$products = getCachedData('products', function() use ($pdo) {
return $pdo->query("SELECT * FROM products")->fetchAll();
});
?>
<?php
// BAD - Inefficient loops
for ($i = 0; $i < count($array); $i++) {
echo $array[$i];
}
// GOOD - Optimized loops
$count = count($array);
for ($i = 0; $i < $count; $i++) {
echo $array[$i];
}
// Even better - foreach
foreach ($array as $item) {
echo $item;
}
?>
<?php
// Set memory limit
ini_set('memory_limit', '256M');
// Process large datasets in chunks
$offset = 0;
$limit = 1000;
do {
$stmt = $pdo->prepare("SELECT * FROM large_table LIMIT ? OFFSET ?");
$stmt->execute([$limit, $offset]);
$rows = $stmt->fetchAll();
foreach ($rows as $row) {
// Process row
}
$offset += $limit;
} while (count($rows) == $limit);
?>
Time: 45 minutes
<?php
function validateFileUpload($file) {
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
$maxSize = 5 * 1024 * 1024; // 5MB
if ($file['error'] !== UPLOAD_ERR_OK) {
return false;
}
if (!in_array($file['type'], $allowedTypes)) {
return false;
}
if ($file['size'] > $maxSize) {
return false;
}
return true;
}
?>
Time: 45 minutes
Next Session: Modern JavaScript Libraries