Search code examples
phpphp-7strpos

PHP 7.0 STRPOS not functioning as expected


So, I was trying to use strpos to test if a string existed in a variable, but in all my attempts to make the if statement work, it was not succeeding, so I went about outputting the string and trying to find the point where strpos detected it, but it was not though it was clearly there! In this case I am searching an SMTP error output for the Gmail SMTP error code.

I know how to fix the error, but I want my system to be able to parse smtp errors and report them to my users...

PHP Code:

$Request = RequestPasswordReset($_POST["email"]);
echo $Request;
echo "<br>Position of Error Code: " . strpos($Request, "gsmtp SMTP code: 550");
die();
if($Request === "SUCCESS") {
    DisplayError("Password Reset Successful", "We have sent a email that contains a link to reset your password.", "/account/resetpassword.php");
} else if($Request === "USER_NOT_FOUND") {
    DisplayError("Password Reset Request Failed", "The specified email is not tied to any accounts in our system.", "/account/resetpassword.php");
} else if(strpos($Request, "gsmtp SMTP code: 550") !== false) {
    DisplayError("Password Reset Request Failed", "The mail was blocked by our relay due to IPs being not whitelisted.", "/account/resetpassword.php");
} else {
    DisplayError("Password Reset Request Failed", "The request failed for an unknown reason.", "/account/resetpassword.php");
}

Text Output:
It does actually repeat itself, I echoed out the $Request twice and it did the following twice exactly

The following From address failed: XXXXXXX : MAIL FROM command failed,Invalid credentials for relay [XXXXXXX]. The IP address you've registered in your G Suite SMTP Relay service doesn't match domain of the account this email is being sent from. If you are trying to relay mail from a domain that isn't registered under your G Suite account or has empty envelope-from, you must configure your mail server either to use SMTP AUTH to identify the sending domain or to present one of your domain names in the HELO or EHLO command. For more information, please visit https://support.google.com/a/answer/6140680#invalidcred r126sm1314271qke.4 - gsmtp ,550,5.7.1SMTP server error: MAIL FROM command failed Detail: Invalid credentials for relay [XXXXXXX]. The IP address you've registered in your G Suite SMTP Relay service doesn't match domain of the account this email is being sent from. If you are trying to relay mail from a domain that isn't registered under your G Suite account or has empty envelope-from, you must configure your mail server either to use SMTP AUTH to identify the sending domain or to present one of your domain names in the HELO or EHLO command. For more information, please visit https://support.google.com/a/answer/6140680#invalidcred r126sm1314271qke.4 - gsmtp SMTP code: 550 Additional SMTP info: 5.7.1
Position of Error Code:

(EDIT) Reset Password Request Function:

function RequestPasswordReset($Email) {
// Try to Get User
$User = GetUser_Email($Email);

// Does user exist?
if($User === "NOT_FOUND") {
  return "USER_NOT_FOUND";
}

// Generate Link To Send with Email
$Link = GeneratePasswordResetLink();
$SendEmail = SendPasswordReset($User["Email"], $User["FirstName"] . $User["LastName"], $Link);

if($SendEmail !== "SUCCESS") {
  return $SendEmail;
} else {
  // WHAT IF MYSQL FAILS????? ~~~~~~~~~~~~~~~ NEED  SOLUTION
  $PDO_Connection = CreateMySQLConnection();
  $PDO_CMD = $PDO_Connection -> prepare("UPDATE accounts SET ResetPassword=? WHERE Email=?");
    $PDO_CMD -> execute(array($Link, $User["Email"]));
  return "SUCCESS";
}
}

(EDIT) Send Password Reset Function:
$User = GetUser_ResetID($resetID);

$mail = CreateSMTPConnection();
$mail->AddAddress($targetAddress, $targetName);       // Add a recipient

$mail->IsHTML(true);                                  // Set email format to HTML
$mail->Subject = 'LitenUp Password Reset';
$mail->Body    = str_replace("https://mylitenup.net/account/resetpassword.php?ID=", ("https://mylitenup.net/account/resetpassword.php?ID=" . $resetID), file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/php/mailer/documents/resetpassword.html"));
$mail->AltBody = 'Reset Your Password: https://mylitenup.net/account/resetpassword.php?ID=' . $resetID;
$mail->XMailer = 'LitenUp Mailer';
$mail->XPriority = '1';

  try{
    $mail->send();
    return "SUCCESS";
  } catch (phpmailerException $e) {
    return $e->errorMessage();
  } catch (\Exception $e) {
    return $e->getMessage();
  }

(EDIT): I tried mb_strpos, but it is not working, so if that is what will work, why is it not working for me? I did mb_strpos($Request, "gsmtp SMTP code: 550");, but after execution it echos the request, but the Position of Error Code: line does not get echoed.

(Update 1): I really apologize for the delay, in a worst case I will extend this again with a bounty. However, you guys were right! When I first had the error, I outputted it and just copied the line "gsmtp SMTP code: 550", but after doing the <pre> tag there appears to be a new line of some sort. You can see in the output that the line should be something more like "gsmtp" + <line break> + " SMTP code: 550", but I am not sure what the line break should be. I tried <br> and \n.


Solution

  • The best solution would be to take the time to isolate exactly what character(s) is in that white-space.

    Until you do that, you can just use regex to gloss over whatever is in there.

    Change:

    } else if(strpos($Request, "gsmtp SMTP code: 550") !== false) {
    

    to:

    } elseif(preg_match("/gsmtp\s+SMTP\s+code:\s+550/",$Request)) {