Task 4 – Video Card Gallery (PHP)
Project Files
The starter index.php has a few hardcoded example cards in the HTML — your job is to replace them with dynamically generated PHP. The img/ folder contains a .jpg for every video, named by video ID.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Task 4.</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<h1>4. Videos</h1>
<div id="main">
<!-- example cards — replace with PHP loop -->
<a class="card very-popular" href="https://www.youtube.com/watch?v=WXwgZL4zx9o" target="_blank">
<img src="img/0573ddf4.jpg">
<h2>Alexander Rybak - Fairytale</h2>
<span class="year">2009</span>
<span class="views">105 million</span>
</a>
<a class="card partially-popular" href="..." target="_blank">
<img src="img/31fb4561.jpg">
<h2>AWS - Viszlát Nyár</h2>
<span class="year">2018</span>
<span class="views">2.6 million</span>
</a>
</div>
</body>
</html>/* index.css — provided, do not modify */
.card { display: inline-block; border: 2px solid grey; padding: 8px; }
.card img { width: 200px; display: block; }
.very-popular { border-color: gold; }
.slightly-popular { border-color: silver; }
.partially-popular { border-color: peru; }Add <?php require '../data/data_array_of_objects.php'; ?> at the top of index.php to load $data — an array of video objects: $video->id, $video->yt, $video->title, $video->year, $video->views, $video->nation. Views is in millions.
Loop over $data and output one <a class="card"> element per video. Use PHP alternative syntax (foreach (): ... endforeach).
Alternative syntax (foreach (): ... endforeach) is the PHP idiom for templates — it avoids mismatched curly braces inside HTML and is easier to read when PHP and HTML are interleaved.
<?= $value ?> is shorthand for <?php echo $value ?>. Use it whenever you output a value inside HTML.
The <a> wraps the whole card so the entire surface is clickable. The href links to the YouTube video using $video->yt (the video ID), and target="_blank" opens it in a new tab.
<?php foreach ($data as $video): ?>
<a class="card"
href="https://www.youtube.com/watch?v=<?= $video->yt ?>"
target="_blank">
<!-- content goes here (subtasks b, c, d) -->
</a>
<?php endforeach; ?> Inside the <a> card, add an <h2> element containing the video title.
$video->title accesses the title property of the PHP object. Objects loaded from data_array_of_objects.php use arrow notation (->) rather than array bracket notation ([]).
htmlspecialchars() converts <, >, ", & to HTML entities, preventing XSS if a title contained special characters. Use it whenever outputting data inside HTML.
<h2><?= htmlspecialchars($video->title) ?></h2> Add a <span class="year"> with the release year and a <span class="views"> with the view count (in millions).
The year and views fields are numbers, so htmlspecialchars() is not necessary (numbers cannot contain HTML-injecting characters). However, using it anyway is not wrong.
The " million" suffix is a plain string appended after the echoed value. The CSS uses the year and views class names to style these spans independently.
<span class="year"><?= $video->year ?></span>
<span class="views"><?= $video->views ?> million</span> Add an <img> element inside the card. The source should be img/{id}.jpg — using the video’s id to build the path. Include an alt attribute.
The img/ folder contains a .jpg for every video ID — e.g. img/0573ddf4.jpg. By embedding $video->id in the src string, you dynamically point to the correct thumbnail for each video.
This is more reliable than YouTube thumbnail URLs (which require a network request) and works offline. The alt attribute is required for accessibility — a description of the image for screen readers.
<img src="img/<?= $video->id ?>.jpg"
alt="<?= htmlspecialchars($video->title) ?>"> Add the correct popularity class to the <a> element: very-popular (≥ 100M views), slightly-popular (≥ 10M), or partially-popular (< 10M). Write a helper function.
Using early returns instead of elseif keeps the function flat and easy to scan. Once a condition matches, PHP returns immediately — the remaining checks are never evaluated.
Always check the highest threshold first. If you checked >= 10 before >= 100, every video with 100M+ views would get slightly-popular and never reach the very-popular check.
Define the function before the foreach loop (in a <?php ... ?> block at the top of the file or before the loop) so it is available when called inside the template.
<?php
function getPopularityClass($views) {
if ($views >= 100) return 'very-popular';
if ($views >= 10) return 'slightly-popular';
return 'partially-popular';
}
?>
<a class="card <?= getPopularityClass($video->views) ?>" ...> Before the loop, sort $data so that the most-viewed video appears first.
usort($array, $callback) sorts an array in place using a custom comparator. The comparator receives two elements and must return negative (keep order), zero (equal), or positive (swap order).
fn($a, $b) => $b->views - $a->views is a PHP arrow function (PHP 7.4+). When $b->views is larger, the result is positive → $b comes before $a → descending order. For ascending, swap to $a->views - $b->views.
Arrow functions capture outer scope automatically (no use keyword), making them cleaner than anonymous functions for simple comparisons.
usort($data, fn($a, $b) => $b->views - $a->views); Complete Solution
<?php
require '../data/data_array_of_objects.php';
function getPopularityClass($views) {
if ($views >= 100) return 'very-popular';
if ($views >= 10) return 'slightly-popular';
return 'partially-popular';
}
usort($data, fn($a, $b) => $b->views - $a->views);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Task 4.</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<h1>4. Videos</h1>
<div id="main">
<?php foreach ($data as $video): ?>
<a class="card <?= getPopularityClass($video->views) ?>"
href="https://www.youtube.com/watch?v=<?= $video->yt ?>"
target="_blank">
<img src="img/<?= $video->id ?>.jpg"
alt="<?= htmlspecialchars($video->title) ?>">
<h2><?= htmlspecialchars($video->title) ?></h2>
<span class="year"><?= $video->year ?></span>
<span class="views"><?= $video->views ?> million</span>
</a>
<?php endforeach; ?>
</div>
</body>
</html>