PHP: Practice Project — Arrays and Functions
You've spent 14 lessons absorbing syntax and functions. Now it's time to tie everything together. These three projects — ranging from simple to ambitious — will let you build real, runnable PHP applications.
1. Setup
Create a practice/ folder inside your htdocs/myphp/ directory and put all your exercise files there. Access them at http://localhost/myphp/practice/.
2. Project One: Shopping Cart
Model a shopping cart with an array — add items, update quantities, remove items, and calculate totals.
<?php
// cart.php — Shopping Cart System
/**
* Add an item to the cart
* @param array $cart Cart array (by reference)
* @param string $name Product name
* @param float $price Unit price
* @param int $qty Quantity (default: 1)
* @return void
*/
function addItem(array &$cart, string $name, float $price, int $qty = 1): void {
if (isset($cart[$name])) {
$cart[$name]['qty'] += $qty;
} else {
$cart[$name] = ['price' => $price, 'qty' => $qty];
}
}
/**
* Update a product's quantity
*/
function updateQty(array &$cart, string $name, int $qty): void {
if ($qty <= 0) {
unset($cart[$name]);
} elseif (isset($cart[$name])) {
$cart[$name]['qty'] = $qty;
}
}
/**
* Remove an item from the cart
*/
function removeItem(array &$cart, string $name): void {
unset($cart[$name]);
}
/**
* Calculate the total price
*/
function getTotal(array $cart): float {
return array_sum(array_map(
fn($item) => $item['price'] * $item['qty'],
$cart
));
}
// === Test the cart ===
$cart = [];
addItem($cart, "PHP Tutorial", 39.90, 2);
addItem($cart, "MySQL Basics", 29.90, 1);
addItem($cart, "PHP Tutorial", 39.90, 1); // Add one more copy
echo "<pre>";
echo "Cart contents:\n";
print_r($cart);
echo "\nTotal: $" . getTotal($cart) . "\n";
// Update quantity
updateQty($cart, "MySQL Basics", 3);
echo "\nAfter update — Total: $" . getTotal($cart) . "\n";
// Remove an item
removeItem($cart, "PHP Tutorial");
echo "\nAfter removal:\n";
print_r($cart);
echo "\nFinal total: $" . getTotal($cart) . "\n";
echo "</pre>";
?>
3. Project Two: To-Do List
Manage tasks with an array — add, complete, delete, filter by status, and sort by priority.
▶ サンプル: Todo Application
<?php
// todo.php — To-Do List
/**
* Add a new task
*/
function addTodo(array &$todos, string $title, string $priority = "medium"): void {
$todos[] = [
'id' => count($todos) + 1,
'title' => $title,
'done' => false,
'priority' => $priority,
'created' => date("Y-m-d H:i:s"),
];
}
/**
* Mark a task as complete
*/
function markDone(array &$todos, int $id): void {
foreach ($todos as &$todo) {
if ($todo['id'] === $id) {
$todo['done'] = true;
break;
}
}
}
/**
* Delete a task
*/
function deleteTodo(array &$todos, int $id): void {
$todos = array_filter($todos, fn($t) => $t['id'] !== $id);
}
/**
* Get all pending (incomplete) tasks
*/
function getPending(array $todos): array {
return array_filter($todos, fn($t) => !$t['done']);
}
/**
* Completion statistics
*/
function getStats(array $todos): array {
$total = count($todos);
$done = count(array_filter($todos, fn($t) => $t['done']));
return ['total' => $total, 'done' => $done, 'pending' => $total - $done];
}
// === Test the Todo app ===
$todos = [];
addTodo($todos, "Learn PHP arrays", "high");
addTodo($todos, "Practice foreach loops", "medium");
addTodo($todos, "Write the cart functions", "high");
addTodo($todos, "Review date functions", "low");
markDone($todos, 1);
markDone($todos, 3);
$stats = getStats($todos);
echo "Total: {$stats['total']} | Done: {$stats['done']} | Pending: {$stats['pending']}<br>";
echo "<h3>Pending Tasks</h3>";
foreach (getPending($todos) as $todo) {
$priorityEmoji = [
'high' => '🔴',
'medium' => '🟡',
'low' => '🟢',
];
echo $priorityEmoji[$todo['priority']] . " {$todo['title']}<br>";
}
?>
4. Project Three: Simple Poll
Use an associative array to store options and vote counts, with support for voting, viewing results, and sorting by votes.
▶ サンプル: Voting System
<?php
// vote.php — Simple Poll
function createPoll(array $options): array {
return array_fill_keys($options, 0);
}
function vote(array &$poll, string $option): bool {
if (!array_key_exists($option, $poll)) {
return false;
}
$poll[$option]++;
return true;
}
function getResults(array $poll): array {
arsort($poll); // Sort by vote count descending
return $poll;
}
function getTotalVotes(array $poll): int {
return array_sum($poll);
}
function getWinner(array $poll): ?string {
$results = getResults($poll);
$maxVotes = max($results);
if ($maxVotes === 0) return null;
return array_key_first($results);
}
// === Test the poll ===
$poll = createPoll(["PHP", "Python", "JavaScript", "Go", "Rust"]);
vote($poll, "PHP");
vote($poll, "PHP");
vote($poll, "JavaScript");
vote($poll, "Python");
vote($poll, "PHP");
vote($poll, "Rust");
vote($poll, "Python");
echo "<h3>Poll Results</h3>";
echo "Total votes: " . getTotalVotes($poll) . "<br>";
$results = getResults($poll);
foreach ($results as $lang => $votes) {
$percent = round($votes / getTotalVotes($poll) * 100, 1);
$bar = str_repeat("█", $votes);
echo "{$lang}: {$bar} {$votes} vote(s) ({$percent}%)<br>";
}
echo "<br>🏆 Leader: " . getWinner($poll) . "<br>";
?>
5. Reflection: From Scripts to Applications
These three projects demonstrate several key ideas:
- Arrays don't just hold data — they can model real business logic.
- Functions encapsulate operations so your code stays clean and composable.
- Pass-by-reference (
&$arr) lets functions modify data structures directly. array_map+ arrow functions make data processing concise and readable.
But you've probably also noticed the limitations:
- All data lives in memory — it vanishes on refresh. (Solved with Sessions / databases later.)
- Code and presentation are mixed together. (Solved with MVC architecture later.)
- There's no form interaction yet. (That's the next lesson.)
❓ よくある質問
array_fill_keys do?array_fill_keys(['a', 'b'], 0) returns ['a' => 0, 'b' => 0] — it sets multiple keys to the same value in one call. We use it in the poll system to initialize every option with zero votes.📖 まとめ
- Shopping cart: associative arrays + pass-by-reference + quantity tracking
- To-do list: multi-dimensional arrays +
array_filterfor filtering + statistics - Voting poll:
array_fill_keysfor initialization +arsortfor ranking +array_key_first - Understanding the "stateless" limitation drives the need for Sessions and databases
📝 練習問題
- Extend the shopping cart with at least 5 products and add a
clearCart()function that removes everything. - Add "sort by priority" (high → medium → low) to the to-do list system.
- Add anti-ballot-stuffing logic to the poll: validate that the option exists before counting a vote, and reject invalid options.