In addition to the magnificent answer from KIKO Software, a few pointers...

Getting IP
---

First of all there is at least one issue connected to security; namely the `findIP()` function. Many beginners are using a similar approach and feeling smart. In reality, this function makes your code *less reliable and secure* as having this very function actually allows the IP to be easily spoofed. See [my other answer](https://codereview.stackexchange.com/a/244194/101565) for the details. **Stick to `REMOTE_ADDR` only** and you're good to go.

Error reporting / Code repetition
---

The amount code repetition (mentioned in the other answer) is just unacceptable (however, it takes some experience to get an eye for the code repetitions and nobody really expects a beginner to catch these). The two code blocks differ by *one symbol* (or so I can tell because finding differences in the identical code blocks is a job by itself).

    $date = '[' . date('d-M-Y h-i-s a') . ']';
    $msg = $e->getMessage();
    $err_msg = $date . ' | Exception Error | ' . $msg  . ' | \n';
    error_log($err_msg, 3, ERROR_LOG_BOOK);
    // error_log("Date/time: $date, Exception Error check error log for more details", 1, WEB_MASTER_EMAIL, "Subject: Exception Error \nfrom: Error Log <" . ERROR_LOG_EMAIL . "> \r\n");

    $date = '[' . date('d-M-Y h-i-s a') . ']';
    $msg = $e->getMessage();
    $err_msg = $date . ' | Error | ' . $msg  . ' | \n';
    error_log($err_msg, 1, ERROR_LOG_BOOK);
    // error_log("Date/time: $date, Error check error log for more details", 1, WEB_MASTER_EMAIL, "Subject: Error \nfrom: Error Log <" . ERROR_LOG_EMAIL . "> \r\n");

Moreover, these almost identical blocks are repeated in the code again!

But what I *really* don't understand is why there is so much attention to the database connection errors as compared to a *complete neglect* towards many other errors in the code! 

Say, connecting to a mail server may result in none the less illustrious error, but we don't see even a hint of the error handling, least such a hairy one. 

Or, including a file may result in the error, when a file is missing or has a permission problem. Or sending a header almost certainly at some point will produce the infamous "Headers already sent" error. Or literally **any line** of **any code** may produce an error. But for some reason, only some code blocks are wrapped in a `try` `catch`.

At least wrap the **entire code** in a single try catch, so that you won't have to repeat the handling code and also it will be able to handle all possible errors, not just a subset of them.

And of course make this code to catch a **single** `\Throwable` class exception with some condition inside to distinguish the type (in case you really need it, which I highly doubt).

The separation of the business logic and presentation logic
---

As you already learned (from the fact you are using `endTheWebpage()`), intertwining the application logic with the presentation logic makes your life incredibly hard. And you must separate them completely:

- make your application code do all of its job first
- only then start sending HTML to the client

This simple approach will make both parts far clearer and easier to understand.