Exercise: Status Codes

Exercise 15 Easy

Prerequisites for the exercise

  1. PHP switch
  2. PHP if...else
  3. All previous chapters

Objective

Given an HTTP status code, print its corresponding status description.

Description

The World Wide Web (WWW), as you may already know, is backed by the HTTP protocol. It relies on a very intuitive and simplistic model of a client and server.

A client, such as a web browser, sends a request for a resource to a server that holds the resource. This request is formally called an HTTP request. Similarly, once the server receives the request and understands what exactly is asked in it, it then responds with an HTTP response.

Each HTTP response has a corresponding status which is comprised of a code and a description.

The status of an HTTP response is meant to specify what happened with the request, for e.g. whether it was responded to successfully, or whether there was an error in the request, or maybe an error in the server's code, and so on and so forth.

A status code, by that means, is the formal way to tell what happened with the request. It's a 3-digit number where the first digit represents the general class that the code belongs to.

For instance, all 2XX codes such as 200, 201, 202 imply 'success'. Similarly, all 4XX codes, such as 401, 402, the well-known 404, represent 'client error'. The list of possible codes is defined by RFC 9110.

Each status code has a corresponding description to make it easy for people to understand the meaning of the status code in HTTP responses, right away. For example, 404 has the description Not Found, which implies that the requested resource doesn't exist on the server.

All the five HTTP status code classes also have corresponding descriptions so that we can get a general idea, just by looking at a status code, of what happened with the sent request.

As defined by RFC 9110, here's the list of all the five classes:

  • 1XX: Informational
  • 2XX: Successful
  • 3XX: Redirection
  • 4XX: Client Error
  • 5XX: Server Error

In this exercise, you have to create a program that asks the user to enter a status code and then outputs a string representing the class that the code belongs to.

Keep in mind that it's possible for the user to enter some arbitrary text as input, likewise you MUST validate the input as follows:

  1. If the length of the text is not 3, output 'Invalid code length.'
  2. Otherwise, if either of the three characters is not a digit, output 'Each character must be a digit.'
  3. Otherwise, if the first digit is not in the range 1-5, output 'First digit not in range 1-5.'

Simple.

Shown below are a couple of examples:

Enter status code> 40c Each character must be a digit.
Enter status code> 20 Invalid code length.
Enter status code> 705 First digit not in range 1-5.
Enter status code> 204 Successful.

Note that your solution MUST use the switch statement.

And you are obviously free to create as many helper functions as you want to, as long as they improve the overall readability and simplicity of the code.

Remember that we haven't structured this exercise to literally pinpoint out-of-range status codes for each code class. For instance, the code 250 isn't defined in RFC 9110, yet it'll work absolutely fine in this program. So, if you want to, you could maybe take the exercise a step further and even check whether the input status code is in-range for its respective class.
View Solution

New file

Inside the directory you created for this course on PHP, create a new folder called Exercise-15-Status-Codes and put the .php solution files for this exercise within it.

Solution

The very first thing we'll do is create a helper function that takes in a status code, as a string, and then returns back the description of the class it belongs to. We'll call this function get_status_code_class().

And since we ought to compare the first digit of the status code with different digits (5 to be precise) in order to determine its class, we'll use a switch in this regard.

Here's the definition of get_status_code_class():

<?php

function get_status_code_class($statusCode) {
   switch ($statusCode[0]) {
      case '1':
         return 'Informational';
      case '2':
         return 'Successful';
      case '3':
         return 'Redirect';
      case '4':
         return 'Client Error';
      case '5':
         return 'Server Error';
   }
}

Next up, we'll create another helper function to determine if a given character represents a digit. We'll call it is_digit(), clearly indiciating that the function returns back a Boolean (by virtue of the word 'is'):

Following is the definition of is_digit():

<?php

function is_digit($char) {
   return '0' <= $char && $char <= '9';
}

Remember that we're assuming that $char is a string, not a number and that's why we compare it with stringified digits, i.e. '0' and '9'.

With this done, we'll define another function, this time to check if the first digit of the status code is in-range. We'll call the function is_first_digit_in_range():

<?php

function is_first_digit_in_range($statusCode) {
   return '1' < $statusCode[0] && $statusCode[0] < '5';
}

With all these three helper functions defined, we can now just go on and lay out a bunch of if and else statements to check whether the given input is valid, and if it is, then output the status code's corresponding class.

Here's the complete code:

<?php

function get_status_code_class($statusCode) {
   switch ($statusCode[0]) {
      case '1':
         return 'Informational';
      case '2':
         return 'Successful';
      case '3':
         return 'Redirect';
      case '4':
         return 'Client Error';
      case '5':
         return 'Server Error';
   }
}

function is_digit($char) {
   return '0' <= $char && $char <= '9';
}

function is_first_digit_in_range($statusCode) {
   return '1' <= $statusCode[0] && $statusCode[0] <= '5';
}


echo 'Enter status code> ';
$statusCode = rtrim(fgets(STDIN));

if (strlen($statusCode) !== 3) {
   echo 'Invalid code length.';
}
elseif (!is_digit($statusCode[0]) || !is_digit($statusCode[1]) || !is_digit($statusCode[2])) {
   echo 'Each character must be a digit.';
}
elseif (!is_first_digit_in_range($statusCode)) {
   echo 'First digit not in range 1-5.';
}
else {
   // The input was valid, hence we must make the desired output.
   echo get_status_code_class($statusCode);
}

Voila!

This isn't the only solution!

Remember that the solution shown above is not the only way to approach the problem described above.

If we want to, we could come up with different kinds of helper functions instead of the ones we created above. Or we could even get done without any helper functions at all, but that would surely make the code a little less readable, especially when we'll have to lay out complex conditions.

For example, instead of using is_digit() manually on each of the three characters of $statusCode, we could create a single is_all_digits() function to encapsulate this entire logic, and then refactor our code as follows:

<?php

/* ... */

if (strlen($statusCode) !== 3) {
   echo 'Invalid code length.';
}
elseif (!is_all_digits($statusCode)) { echo 'Each character must be a digit.'; } elseif (!is_first_digit_in_range($statusCode)) { echo 'First digit not in range 1-5.'; } else { // The input was valid, hence we must make the desired output. echo get_status_code_class($statusCode); }

There are just tons and tons of ways to approach the same problem.

Whatever solution you're able to come up with, it should essentially meet the following two prerequisites in order to be classified as a perfect one:

  • Obviously produce the correct output.
  • Be simple and readable.