有没有办法使用 Zend-Mail 验证 SMTP 配置?
Is there a way to validate an SMTP configuration using Zend-Mail?
我一直在 PHP 中开发一个 class 来发送邮件,我决定使用 Zend 框架。 class 使用用户的 SMTP 配置发送邮件。截至目前,我正在使用提供的用户凭据检查用户的 SMTP 配置,并向 "dummy" 电子邮件地址发送 "dummy" 电子邮件,并捕获 ZendException
class 可能会出错。这是一个可怕的方法,原因有很多:
- SMTP 用户最终因涉嫌 "Spamming" (GMail)
而被禁止
- 低效且耗时
- 用户邮箱中的电子邮件发送尝试失败
以下是我正在做的测试 SMTP 配置是否有效的示例:
public function validSMTP () {
// Get the user's SMTP configuration
$config = $this->getConfiguration ();
// Create a new Zend transport SMTP object
$transport = new Zend_Mail_Transport_Smtp ( $config ["hostname"], [
"auth" => "login",
"ssl" => $config ["protocol"],
"port" => $config ["port"],
"username" => $config ["from"],
"password" => $config ["password"]
]);
// Create a new message and send it to dummy email
$mail = new Zend_Mail ("UTF-8");
$mail->setBodyText ( "null" );
$mail->setFrom ( $config ["from"] );
$mail->addTo ( "dev@null.com" );
$mail->setSubject ( "Test" );
// Attempt to send the email
try {
// Send the email out
$mail->send ( $transport );
// If all is well, return true
return true;
}
// Catch all Zend exceptions
catch ( Zend_Exception $exception ) {
// Invalid configuration
return false;
}
}
所以我的问题是:有更好的方法吗? Zend_Mail 有这样的内置功能吗?我找遍了,找不到 Zend_Mail 中的任何内容。预先感谢任何回答的人!
我在 documentation 中没有看到任何内容表明有一种方法可以在不实际尝试发送邮件的情况下仅测试 SMTP 身份验证。也许当您调用 setOptions
或 setConnectionConfig
时,它会尝试登录并在失败时抛出异常,但我怀疑不会。
与其在每次发送邮件时都执行验证检查,不如将配置数据和验证结果保存在一个文件中。然后在进行 SMTP 检查之前,读取文件并检查配置设置是否相同。如果是,只是 return 保存的结果。
这解决了您问题列表中的前两项,如果他们的配置无效,他们只会在第一次收到退回电子邮件。
我决定手动检查,我将post下面的最终结果,以便将来对某人有所帮助。感谢@Barmar 帮助我搜索文档并得出 Zend_Mail 框架不支持此功能的结果。不幸的是,以下方法仅适用于 SSL,因为 TLS 涉及在 EHLO 命令(以及更多)之后进行加密。如果配置有效,则 returns true,否则 returns 字符串形式无效的原因。
public function validSMTP () {
// Initialize client configuration, for this example
$config = [
"hostname" => "smtp.gmail.com",
"port" => 465,
"protocol" => "ssl",
"username" => "USERNAME",
"password" => "PASSWORD",
];
// Add the connection url based on protocol
$config ["url"] = $config ["protocol"] . "://" . $config ["hostname"];
// Open a new socket connection to the SMTP mail server
if ( !( $socket = fsockopen ( $config ["url"], $config ["port"], $en, $es, 15 ) ) ) {
// Could not establish connection to host
return "Connection failed, check hostname/port?";
}
// Make sure that the protocol is correct
if ( $this->status_match($socket, '220') === false ) {
// Probably a wrong protocol (SSL/TLS)
return "Connection failed, check protocol?";
}
// Send hello message to server
fwrite ( $socket, "EHLO " . $config ["hostname"] ."\r\n" );
if ( $this->status_match ( $socket, "250" ) === false ) {
// If Hello fails, say config is invalid
return "Invalid SMTP configuration";
}
// Request to login
fwrite ( $socket, "AUTH LOGIN\r\n" );
if ( $this->status_match ( $socket, "334" ) === false ) {
return "Invalid SMTP configuration";
}
// Send the username
fwrite ( $socket, base64_encode ( $config [ "username" ] ) . "\r\n" );
if ( $this->status_match ( $socket, "334" ) === false ) {
// If failed, warn that invalid username password was passed
return "Invalid username/password combination.";
}
// Send the password
fwrite ( $socket, base64_encode ( $config [ "password" ] ) . "\r\n" );
if ( $this->status_match ( $socket, "235" ) === false ) {
// If failed, warn that invalid username password was passed
return "Invalid username/password combination.";
}
// Close the socket connections
fclose ( $socket );
// Return true, if everything above passed
return true;
}
private function status_match ( $socket, $expected ) {
// Initialize the response string
$response = '';
// Get response until nothing but code is visible
while ( substr ( $response, 3, 1) != ' ' ) {
// Receive 250 bytes
if ( !( $response = fgets ( $socket, 256 ) ) ) {
// Break if nothing else to read
break;
}
}
// If the status code is not what was expected
if ( !( substr ( $response, 0, 3 ) == $expected ) ) {
// Return false
return false;
}
// Otherwise return true
return true;
}
我通过使用以下示例想出了这个:http://schoudhury.com/blog/articles/send-email-using-gmail-from-php-with-fsockopen/
我一直在 PHP 中开发一个 class 来发送邮件,我决定使用 Zend 框架。 class 使用用户的 SMTP 配置发送邮件。截至目前,我正在使用提供的用户凭据检查用户的 SMTP 配置,并向 "dummy" 电子邮件地址发送 "dummy" 电子邮件,并捕获 ZendException
class 可能会出错。这是一个可怕的方法,原因有很多:
- SMTP 用户最终因涉嫌 "Spamming" (GMail) 而被禁止
- 低效且耗时
- 用户邮箱中的电子邮件发送尝试失败
以下是我正在做的测试 SMTP 配置是否有效的示例:
public function validSMTP () {
// Get the user's SMTP configuration
$config = $this->getConfiguration ();
// Create a new Zend transport SMTP object
$transport = new Zend_Mail_Transport_Smtp ( $config ["hostname"], [
"auth" => "login",
"ssl" => $config ["protocol"],
"port" => $config ["port"],
"username" => $config ["from"],
"password" => $config ["password"]
]);
// Create a new message and send it to dummy email
$mail = new Zend_Mail ("UTF-8");
$mail->setBodyText ( "null" );
$mail->setFrom ( $config ["from"] );
$mail->addTo ( "dev@null.com" );
$mail->setSubject ( "Test" );
// Attempt to send the email
try {
// Send the email out
$mail->send ( $transport );
// If all is well, return true
return true;
}
// Catch all Zend exceptions
catch ( Zend_Exception $exception ) {
// Invalid configuration
return false;
}
}
所以我的问题是:有更好的方法吗? Zend_Mail 有这样的内置功能吗?我找遍了,找不到 Zend_Mail 中的任何内容。预先感谢任何回答的人!
我在 documentation 中没有看到任何内容表明有一种方法可以在不实际尝试发送邮件的情况下仅测试 SMTP 身份验证。也许当您调用 setOptions
或 setConnectionConfig
时,它会尝试登录并在失败时抛出异常,但我怀疑不会。
与其在每次发送邮件时都执行验证检查,不如将配置数据和验证结果保存在一个文件中。然后在进行 SMTP 检查之前,读取文件并检查配置设置是否相同。如果是,只是 return 保存的结果。
这解决了您问题列表中的前两项,如果他们的配置无效,他们只会在第一次收到退回电子邮件。
我决定手动检查,我将post下面的最终结果,以便将来对某人有所帮助。感谢@Barmar 帮助我搜索文档并得出 Zend_Mail 框架不支持此功能的结果。不幸的是,以下方法仅适用于 SSL,因为 TLS 涉及在 EHLO 命令(以及更多)之后进行加密。如果配置有效,则 returns true,否则 returns 字符串形式无效的原因。
public function validSMTP () {
// Initialize client configuration, for this example
$config = [
"hostname" => "smtp.gmail.com",
"port" => 465,
"protocol" => "ssl",
"username" => "USERNAME",
"password" => "PASSWORD",
];
// Add the connection url based on protocol
$config ["url"] = $config ["protocol"] . "://" . $config ["hostname"];
// Open a new socket connection to the SMTP mail server
if ( !( $socket = fsockopen ( $config ["url"], $config ["port"], $en, $es, 15 ) ) ) {
// Could not establish connection to host
return "Connection failed, check hostname/port?";
}
// Make sure that the protocol is correct
if ( $this->status_match($socket, '220') === false ) {
// Probably a wrong protocol (SSL/TLS)
return "Connection failed, check protocol?";
}
// Send hello message to server
fwrite ( $socket, "EHLO " . $config ["hostname"] ."\r\n" );
if ( $this->status_match ( $socket, "250" ) === false ) {
// If Hello fails, say config is invalid
return "Invalid SMTP configuration";
}
// Request to login
fwrite ( $socket, "AUTH LOGIN\r\n" );
if ( $this->status_match ( $socket, "334" ) === false ) {
return "Invalid SMTP configuration";
}
// Send the username
fwrite ( $socket, base64_encode ( $config [ "username" ] ) . "\r\n" );
if ( $this->status_match ( $socket, "334" ) === false ) {
// If failed, warn that invalid username password was passed
return "Invalid username/password combination.";
}
// Send the password
fwrite ( $socket, base64_encode ( $config [ "password" ] ) . "\r\n" );
if ( $this->status_match ( $socket, "235" ) === false ) {
// If failed, warn that invalid username password was passed
return "Invalid username/password combination.";
}
// Close the socket connections
fclose ( $socket );
// Return true, if everything above passed
return true;
}
private function status_match ( $socket, $expected ) {
// Initialize the response string
$response = '';
// Get response until nothing but code is visible
while ( substr ( $response, 3, 1) != ' ' ) {
// Receive 250 bytes
if ( !( $response = fgets ( $socket, 256 ) ) ) {
// Break if nothing else to read
break;
}
}
// If the status code is not what was expected
if ( !( substr ( $response, 0, 3 ) == $expected ) ) {
// Return false
return false;
}
// Otherwise return true
return true;
}
我通过使用以下示例想出了这个:http://schoudhury.com/blog/articles/send-email-using-gmail-from-php-with-fsockopen/