I have a contact form with a privacy consent checkbox which the user has to check. If they don't, a required error message should appear, as it successfully does for the other fields.
The problem is that I'm getting an Undefined index: privacy notice for the checkbox if it's unchecked. If I submit the form with it checked, then it works. 
I understand that if the checkbox is unchecked, PHP basically doesn't know it exists, therefore it doesn't send the data to $_POST.
All the forum posts I read mention using isset() or empty() to fix this, but I'm already using it and used it in different ways to try things out.
It's probably something obvious, but I just can't figure it out for the past several hours.
Here's a part of the validation class:
class ValidateContactForm
{
    private $data;
    private $file;
    private static $fields = [
        'name',
        'email',
        'subject',
        'message',
        'privacy'
    ];
    private static $fileInput = 'file';
    private $errors = [];
    public function __construct($postData, $fileData)
    {
        $this->data = $postData;
        $this->file = $fileData;
    }
    public function validateForm()
    {
        // foreach (self::$fields as $field) {
        //     if (!array_key_exists($field, $this->data)) {
        //         trigger_error('An input key does not have a match in the array', E_USER_NOTICE);
        //         return;
        //     }
        // }
        if (!array_key_exists(self::$fileInput, $this->file)) {
            trigger_error('The file input key does not match', E_USER_NOTICE);
        }
        $this->validateName();
        $this->validateEmail();
        $this->validateSubject();
        $this->validateMessage();
        $this->validatePrivacy();
        $this->validateFile();
        return $this->errors;
    }
    private function validatePrivacy()
    {
        $val = $this->data['privacy'];
        if (empty($val)) {
            $this->addError('privacy', 'The privacy checkbox is required.');
        }
    }
The validatePrivacy() method checks if $_POST['privacy'] is empty.
Here's the part of the contact form class where I check if the fields are set:
class ContactForm
{
    public function sendContactForm()
    {
        if ($_POST['name'] != ''
            && $_POST['email'] != ''
            && $_POST['message'] != ''
            && $_POST['subject'] != ''
            && !empty($_POST['privacy'])
        ) {
            $name = $this->sanitize($_POST['name']);
            $email = $this->sanitize($_POST['email']);
            $message = $this->sanitize($_POST['message']);
            $subject = $this->sanitize($_POST['subject']);
            $privacy = $_POST['privacy'];
I also tried isset($_POST['privacy']) and $_POST['privacy'] != ''.
Here's a part of the file with the instantiation and HTML:
<?php
require_once 'includes/head.php';
require_once 'vendor/autoload.php';
use App\ContactForm;
use App\Validation\ValidateContactForm;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $validation = new ValidateContactForm($_POST, $_FILES);
    $errors = $validation->validateForm();
    if (empty($errors)) {
        $contactForm = new ContactForm;
        $sendContactForm = $contactForm->sendContactForm();
        if (!headers_sent()) {            
            header('Location:' . htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES) . '?' . 'sent');
            exit;
        }
    }
}
?>
<div class="form-group form-check">
    <input type="checkbox" name="privacy" class="form-check-input <?php echo isset($errors['privacy']) ? 'is-invalid' : ''; ?>" id="inputCheckbox" value="yes">
    <label class="form-check-label" for="inputCheckbox">I understand that this information will be collected in order to be contacted and process a potential order. *</label>
    <p class="invalid-feedback"><?php echo $errors['privacy'] ?? ''; ?></p>                                              
</div>
If I use vard_dump on it, it returns null, but I assume it's expected behavior since it doesn't exist unless the checkbox is checked.
I know I can use the HTML required attribute (and I will use that, too) or JavaScript, but I'd like to rely more on server validation. I also want to learn this stuff and not give in to workarounds.
 
     
     
    