PHP script that returns an error message based on what $_POST parameters are missing I have a script that checks if the specified set of $_POST variables are supplied and not empty and returns an error string that is human readable.
Here's my code:
if ($_SERVER[&quot;REQUEST_METHOD&quot;] === &quot;POST&quot;) {
    // Local variables initialization
    $missing = [];

    $checkVariables = [
        'name', 'address', 'contact'
    ];

    // Check for nulls or non existent payload
    foreach ($checkVariables as $item) {
        if (empty($_POST[$item]) || !array_key_exists($item, $_POST)) {
            $missing[] = $item;
        }
    }

    $missingCount = count($missing);
    if ($missingCount &gt; 0) {
        $missingString = '';

        if ($missingCount === 1) {
            $missingString = $missing[0];
        } else if ($missingCount === 2) {
            $missingString = implode(' and ', $missing);
        } else {
            $lastItem = array_pop($missing);
            $partialMissingString = implode(', ', $missing);

            $missingString = $partialMissingString . &quot;, and {$lastItem}&quot;;
        }

        $verb = $missingCount &gt; 1 ? 'are' : 'is';
        $field = $missingCount &gt; 1 ? 'fields' : 'field';
        $errorString = &quot;Incomplete information received. &quot; .
            &quot;The {$missingString} {$field} {$verb} missing. &quot; .
            &quot;Please check your inputs and try again.&quot;;

        // Exits the script
        OutputResponse::sendResponse(400, $errorString);
    }
    // if there's no missing continue running the script
    // more code here but it's not the focus of this code review
}

My OutputResponse code:
class OutputResponse
{
    public static function sendResponse(string $statusCode, $messageBody): void
    {
        if ($statusCode == 500) {
            header(&quot;HTTP/1.1 500 Internal Server Error&quot;);
        } else if ($statusCode == 405) {
            header('HTTP/1.1 405 Method Not Allowed');
        } else if ($statusCode == 404) {
            header(&quot;HTTP/1.1 404 Not Found&quot;);
        } else if ($statusCode == 403) {
            header(&quot;HTTP/1.1 403 Forbidden&quot;);
        } else if ($statusCode == 401) {
            header(&quot;HTTP/1.1 401 Unauthorized&quot;);
        } else if ($statusCode == 400) {
            header(&quot;HTTP/1.1 400 Bad Request&quot;);
        } else {
            header(&quot;HTTP/1.1 200 OK&quot;);
        }

        header('Content-Type: application/json');
        echo json_encode([
            'code' =&gt; $statusCode,
            'data' =&gt; $messageBody
        ]);

        exit;
    }
}


The script expects $_POST['name'], $_POST['address'], and $_POST['contact'] to be not null or empty. The array keys to be checked are in the $checkVariables array.
For simplification, I'm dropping the $_POST in the next examples.
If name is the only one missing:
{
    &quot;code&quot;: &quot;400&quot;,
    &quot;data&quot;: &quot;Incomplete information received. The name field is missing. Please check your inputs and try again.&quot;
}

If name and contact are missing:
{
    &quot;code&quot;: &quot;400&quot;,
    &quot;data&quot;: &quot;Incomplete information received. The name and contact fields are missing. Please check your inputs and try again.&quot;
}

If all three are missing:
{
    &quot;code&quot;: &quot;400&quot;,
    &quot;data&quot;: &quot;Incomplete information received. The name, address, and contact fields are missing. Please check your inputs and try again.&quot;
}


Personally, the part on the if ($missingCount &gt; 0) block is the messiest or unoptimized.
Any improvements or critiques are welcome!
if (empty($_POST[$item]) || !array_key_exists($item, $_POST)) { is literally checking if $_POST[$item] is not declared or is falsey THEN checking if $_POST[$item] is not declared.

// Check for nulls or non existent payload


The comment associated with the step indicates that you want to check if $_POST elements are not declared or are null.  In this case, you should only use: if (!isset($_POST[$item])) {.
If you want to check that elements are not declared or empty/falsey, then use:if (empty($_POST[$item])) {.

if ($missingCount &gt; 0) { can be safely reduced to if ($missingCount) { which checks if the count is &quot;truthy&quot; (in other words, not zero).

else if is one word in php, please always type elseif to comply with PSR guidelines.

Don't bother declaring $missingString = ''; if you are unconditionally going to overwrite it anyhow.

You can combine the if and first else if because if the array only has one element, then no glue will be used while producing the output string.
if ($missingCount &lt; 3) {
     $missingString = implode(' and ', $missing);
}


The &quot;smart-implode&quot; as I've seen it referred to at least once on StackOverflow is fine enough.  There are a few other ways to do it -- I'll show another one below.

The whole chunk of code that crafts the OutputResponse might look like this: (Demo).  The advantages are: fewest declared variables (specifically no single-use variables), not repeated function calls, and the elegance of sprintf() when injecting variables into a string.
$missingCount = count($missing);
if ($missingCount) {
    if ($missingCount &lt; 3) {
         $glue = ' and ';
    } else {
         $glue = ', ';
         $missing[] = 'and ' . array_pop($missing);
    }
    OutputResponse::sendResponse(
        400,
        sprintf(
            'Incomplete information received. The %s %s missing. Please check your inputs and try again.',
            implode($glue, $missing),
            $missingCount === 1 ? 'field is' : 'fields are'
        )
    );
}


[EDITED] After reading the other reviews and learning that my recommended lookup array was incomplete, flawed, and frankly suboptimal, I now find myself agreeing with YourCommonSense's advice to use http_response_code() for setting the HTTP response code.  See this Stack Overflow page for additional considerations and fringe cases around the native function which was available since PHP5.4. Also,  Now I suppose my new code for the sendResponse() method would look like this:
 http_response_code($statusCode);
 header('Content-Type: application/json');
 exit(
     json_encode([
         'code' =&gt; $statusCode,
         'data' =&gt; $messageBody
     ])
 );