Random Dog Gallery app

Sometimes the best way to learn a new API is to build something small, fun, and visual. That’s exactly what happened with my latest mini-project: a Random Dog Gallery built in plain PHP. No frameworks, no build tools—just a single file, a public API, and a few lines of cURL.

Here’s the full story: what it does, how it works, and the decisions I made along the way.

The Idea

I wanted an app that:

  • Fetches random dog images from a free API

  • Displays them in a clean, responsive grid

  • Refreshes with a single click

  • Handles errors gracefully

The API

I used Dog CEO’s API—one of the friendliest public APIs out there. No API key required, and the endpoint is simple:

API

Fetching the Data with cURL

function dog_app($link) {
    $ch = curl_init($link);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 ...');
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);

    $results = curl_exec($ch);
    curl_close($ch);
    return $results;
}
  • RETURNTRANSFER – so curl_exec() returns the response instead of printing it.

  • TIMEOUT: 10 – no point hanging forever if the API is slow.

  • USERAGENT – some servers block default cURL requests, so I sent a browser-like one.

  • FOLLOWLOCATION – just in case the endpoint redirects.

Parsing the Response

Once I have the raw JSON, decoding is straightforward:

php
$response = dog_app("https://dog.ceo/api/breeds/image/random/6");
$data     = json_decode($response, true);

if (isset($data['message']) && is_array($data['message'])) {
    $picha_zote = $data['message'];   // "picha zote" = "all photos" in Swahili
} else {
    $error = "Could not reach the dog API. Please try again.";
}

Error Handling

If the API call fails, I show a Bootstrap alert instead of a broken grid:

php
<?php if ($error): ?>
    <div class="alert alert-warning text-center"><?php echo htmlspecialchars($error); ?></div>
<?php endif; ?>

Using htmlspecialchars() on any dynamic output is a small but essential habit—it prevents injected strings from breaking your markup.

What I Learned

  1. Public APIs are the fastest way to level up. You don’t need a big project to practice real-world patterns like error handling, timeouts, and parsing.

  2. Small UX details carry a lot of weight. Lazy loading, hover transitions, and placeholder fallbacks cost almost nothing but make the app feel polished.

  3. Plain PHP is still powerful. You don’t always need a framework—sometimes a single file and a cURL call is the whole app.

What’s Next

Some features I’d like to add:

  • Breed filtering – let users pick a specific breed instead of pure random.

  • Favorites – save liked photos to localStorage.

 

The UI: Bootstrap + a Bit of Custom CSS