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
<?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>";
?>
💡 Tip: This cart stores all data in memory — refreshing the page clears everything. In Lesson 21, once you learn about Sessions, your cart will remember your items across page loads.


3. Project Two: To-Do List

Manage tasks with an array — add, complete, delete, filter by status, and sort by priority.

▶ サンプル: Todo Application

PHP 📖 参照専用
<?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>";
}
?>
論理コード 48 行(40 行制限超過、参照専用)

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 📖 参照専用
<?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>";
?>
論理コード 42 行(40 行制限超過、参照専用)

5. Reflection: From Scripts to Applications

These three projects demonstrate several key ideas:

But you've probably also noticed the limitations:

❓ よくある質問

Q Why use an associative array for the cart instead of an indexed one?
A Associative arrays use the product name as a key, giving you O(1) lookups and updates. An indexed array would require scanning to find items, which gets slow as the cart grows.
Q What does array_fill_keys do?
A 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.
Q Will data persist between page loads?
A No — refreshing the page wipes everything. This is PHP's "stateless" nature. In Lesson 21, you'll learn about Sessions, which let your cart data survive across requests within the same user session.

📖 まとめ

📝 練習問題

  1. Extend the shopping cart with at least 5 products and add a clearCart() function that removes everything.
  2. Add "sort by priority" (high → medium → low) to the to-do list system.
  3. Add anti-ballot-stuffing logic to the poll: validate that the option exists before counting a vote, and reject invalid options.
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%