PHP Fundamentals
Executing Queries with MySQLi
Executing SQL Queries
Once connected to the database, you can execute SQL queries to create, read, update, and delete data. MySQLi provides several methods for executing queries.
The query() Method
The simplest way to execute a query is using the query() method:
<?php
require_once 'database.php';
// Execute a simple query
$sql = "SELECT * FROM users";
$result = $conn->query($sql);
if ($result) {
echo "Query executed successfully";
} else {
echo "Error: " . $conn->error;
}
?>
Warning: NEVER use
query() with user input directly. This example uses hardcoded SQL. We'll learn about prepared statements in the next lesson.
Creating Tables
Let's create a users table for our examples:
<?php
require_once 'database.php';
$sql = "CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
full_name VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)";
if ($conn->query($sql) === TRUE) {
echo "Table created successfully";
} else {
echo "Error creating table: " . $conn->error;
}
?>
Inserting Data
Insert new records into the database:
<?php
require_once 'database.php';
// Hash the password
$password = password_hash("mypassword123", PASSWORD_DEFAULT);
$sql = "INSERT INTO users (username, email, password, full_name)
VALUES ('johndoe', 'john@example.com', '$password', 'John Doe')";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully<br>";
echo "Last inserted ID: " . $conn->insert_id;
} else {
echo "Error: " . $conn->error;
}
?>
Note: The
insert_id property returns the ID of the last inserted row. Very useful when you need to reference the new record.
Selecting Data
Retrieve data from the database and process the results:
Fetching All Rows
<?php
require_once 'database.php';
$sql = "SELECT id, username, email, full_name, created_at FROM users";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<h3>Users List</h3>";
echo "<table border='1'>";
echo "<tr><th>ID</th><th>Username</th><th>Email</th><th>Full Name</th></tr>";
// Fetch each row as associative array
while ($row = $result->fetch_assoc()) {
echo "<tr>";
echo "<td>" . $row['id'] . "</td>";
echo "<td>" . $row['username'] . "</td>";
echo "<td>" . $row['email'] . "</td>";
echo "<td>" . $row['full_name'] . "</td>";
echo "</tr>";
}
echo "</table>";
} else {
echo "No users found";
}
// Free result set
$result->free();
?>
Different Fetch Methods
<?php // 1. Fetch as associative array (key = column name) $row = $result->fetch_assoc(); // Usage: $row['username'] // 2. Fetch as numeric array (key = column index) $row = $result->fetch_row(); // Usage: $row[0], $row[1] // 3. Fetch as both associative and numeric $row = $result->fetch_array(MYSQLI_BOTH); // Usage: $row['username'] or $row[0] // 4. Fetch as object $row = $result->fetch_object(); // Usage: $row->username // 5. Fetch all rows at once $rows = $result->fetch_all(MYSQLI_ASSOC); // Returns 2D array of all rows ?>
Tip:
fetch_assoc() is most commonly used because column names are more readable than numeric indices.
Updating Data
Modify existing records in the database:
<?php
require_once 'database.php';
$sql = "UPDATE users
SET full_name = 'John Smith', email = 'johnsmith@example.com'
WHERE username = 'johndoe'";
if ($conn->query($sql) === TRUE) {
echo "Record updated successfully<br>";
echo "Rows affected: " . $conn->affected_rows;
} else {
echo "Error updating record: " . $conn->error;
}
?>
Note: The
affected_rows property tells you how many rows were modified. Returns 0 if no rows matched the WHERE clause.
Deleting Data
Remove records from the database:
<?php
require_once 'database.php';
$sql = "DELETE FROM users WHERE username = 'johndoe'";
if ($conn->query($sql) === TRUE) {
echo "Record deleted successfully<br>";
echo "Rows deleted: " . $conn->affected_rows;
} else {
echo "Error deleting record: " . $conn->error;
}
?>
Warning: Always include a WHERE clause in UPDATE and DELETE statements, or you'll modify/delete ALL rows!
Counting Rows
Get the number of rows returned by a SELECT query:
<?php require_once 'database.php'; $sql = "SELECT * FROM users WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)"; $result = $conn->query($sql); echo "Users registered in last 7 days: " . $result->num_rows; $result->free(); ?>
Using LIMIT and OFFSET
Implement pagination by limiting the number of results:
<?php
require_once 'database.php';
// Pagination settings
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$per_page = 10;
$offset = ($page - 1) * $per_page;
// Get total number of users
$count_sql = "SELECT COUNT(*) as total FROM users";
$count_result = $conn->query($count_sql);
$total_users = $count_result->fetch_assoc()['total'];
$total_pages = ceil($total_users / $per_page);
// Get users for current page
$sql = "SELECT * FROM users ORDER BY created_at DESC LIMIT $per_page OFFSET $offset";
$result = $conn->query($sql);
echo "<h3>Users (Page $page of $total_pages)</h3>";
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "<p>" . $row['username'] . " - " . $row['email'] . "</p>";
}
}
// Pagination links
for ($i = 1; $i <= $total_pages; $i++) {
if ($i === $page) {
echo "<strong>$i</strong> ";
} else {
echo "<a href='?page=$i'>$i</a> ";
}
}
?>
Checking if Record Exists
Verify if a record exists before performing operations:
<?php
require_once 'database.php';
function userExists($conn, $username) {
$sql = "SELECT id FROM users WHERE username = '$username'";
$result = $conn->query($sql);
return $result->num_rows > 0;
}
if (userExists($conn, 'johndoe')) {
echo "Username already taken";
} else {
echo "Username available";
}
?>
Multi-Query Execution
Execute multiple queries in one call:
<?php
require_once 'database.php';
$sql = "
INSERT INTO users (username, email, password) VALUES ('user1', 'user1@test.com', 'pass1');
INSERT INTO users (username, email, password) VALUES ('user2', 'user2@test.com', 'pass2');
INSERT INTO users (username, email, password) VALUES ('user3', 'user3@test.com', 'pass3');
";
if ($conn->multi_query($sql)) {
do {
// Store first result set
if ($result = $conn->store_result()) {
$result->free();
}
if ($conn->more_results()) {
echo "More results coming...<br>";
}
} while ($conn->next_result());
echo "All queries executed successfully";
} else {
echo "Error: " . $conn->error;
}
?>
Warning:
multi_query() is rarely needed and can be dangerous with user input. Prefer executing queries separately.
Complete CRUD Example
Here's a complete example combining all operations:
<?php
require_once 'database.php';
class UserManager {
private $conn;
public function __construct($connection) {
$this->conn = $connection;
}
// CREATE
public function createUser($username, $email, $password, $full_name) {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$sql = "INSERT INTO users (username, email, password, full_name)
VALUES ('$username', '$email', '$hashed_password', '$full_name')";
if ($this->conn->query($sql)) {
return $this->conn->insert_id;
}
return false;
}
// READ
public function getUser($id) {
$sql = "SELECT * FROM users WHERE id = $id";
$result = $this->conn->query($sql);
if ($result->num_rows > 0) {
return $result->fetch_assoc();
}
return null;
}
public function getAllUsers() {
$sql = "SELECT * FROM users ORDER BY created_at DESC";
$result = $this->conn->query($sql);
return $result->fetch_all(MYSQLI_ASSOC);
}
// UPDATE
public function updateUser($id, $data) {
$updates = [];
foreach ($data as $key => $value) {
$updates[] = "$key = '$value'";
}
$updates_str = implode(', ', $updates);
$sql = "UPDATE users SET $updates_str WHERE id = $id";
return $this->conn->query($sql);
}
// DELETE
public function deleteUser($id) {
$sql = "DELETE FROM users WHERE id = $id";
return $this->conn->query($sql);
}
// COUNT
public function getUserCount() {
$sql = "SELECT COUNT(*) as total FROM users";
$result = $this->conn->query($sql);
$row = $result->fetch_assoc();
return $row['total'];
}
}
// Usage
$userManager = new UserManager($conn);
// Create user
$user_id = $userManager->createUser('alice', 'alice@example.com', 'password123', 'Alice Smith');
echo "Created user with ID: $user_id<br>";
// Get user
$user = $userManager->getUser($user_id);
echo "Username: " . $user['username'] . "<br>";
// Update user
$userManager->updateUser($user_id, ['full_name' => 'Alice Johnson']);
echo "User updated<br>";
// Get all users
$all_users = $userManager->getAllUsers();
echo "Total users: " . count($all_users) . "<br>";
// Delete user
$userManager->deleteUser($user_id);
echo "User deleted<br>";
?>
Security Alert: This example uses direct string concatenation for simplicity. NEVER do this with user input! We'll learn prepared statements in the next lesson.
Exercise: Build a Simple User Directory
- Create a
userstable with fields: id, name, email, phone, city - Create an
add_user.phpform to add new users - Create a
list_users.phppage to display all users in a table - Add a search feature to filter users by city
- Add pagination to show 5 users per page
- Create an
edit_user.phppage to update user information - Create a
delete_user.phpscript to remove users - Add a counter showing total number of users
Best Practices
- Always check query results: Verify if queries executed successfully
- Free result sets: Use
$result->free()to release memory - Use specific column names: SELECT specific columns instead of SELECT *
- Always include WHERE in UPDATE/DELETE: Prevent accidental mass changes
- Close connections: Close database connections when done
- Never trust user input: Always use prepared statements (next lesson)
- Use transactions: For operations that must succeed or fail together
Summary
- Use
query()method to execute SQL statements insert_idreturns the ID of the last inserted rowaffected_rowsreturns the number of rows affected by UPDATE/DELETEnum_rowsreturns the number of rows in a SELECT result- Use
fetch_assoc()to retrieve rows as associative arrays - Always free result sets with
free()when done - Never concatenate user input directly into SQL queries