Some advice:
1) You are checking if the second field is empty AFTER you try to do an operation on it. Always check your empty BEFORE proceding forward.
2) Whitespace is your friend, it could greatly clarify your code.
3) there's more to checking e-mails than filter_var... which fails to check specific lengths to domain validity.
4) you don't need to validate both if they have to be EQUAL!
First off let's get you a more robust mail check function:
function isValidEmail($address) {
if (filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) return false;
[$local, $domain] = explode('@', $address);
$localLength = strlen($local);
$domainLength = strlen($domain);
return (
($localLength > 0 && $localLength < 65) &&
($domainLength > 3 && $domainLength < 256) &&
(checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A'))
);
} // isValidEmail
Beware the rdns lookups can add some delay if you're server is misconfigured or just sucks at it, but it's usually worth it to reject made up garbage domains.
Then your error logic can be simplified down to:
if (
empty($email) ||
empty($email1) ||
($email != $email1) ||
!isValidEmail($email)
) $errors[] = "Email Addresses are Invalid";
Though I suspect you've got "variables for nothing" in there, since there's nothing there that couldn't (or shouldn't) be done directly on $_POST.
if (
empty($_POST['email']) ||
empty($_POST['email_duplicate') ||
($_POST['email'] != $_POST['email_duplicate']) ||
!isValidEmail($_POST['email'])
) $errors[] = "Email Addresses are Invalid";
This isn't JavaScript where array or object lookups are slow as molasses in February, you don't need to be making extra variables for everything; as that usually ends up being variables for nothing.
Note I put the robust check function last in the testing so that the simple/smaller/faster checks are done first -- that way short circuit eval can exit prematurely when appropriate.