我使用 phpmailer 通过 smtp.google.com 服务器发送邮件,但现在它无法正常工作,因为他们说使用 OAuth2.0 配置。
我参考了一些示例并使用使用 PhpMailer 和 Gmail XOAUTH2 发送电子邮件创建了一个示例页面来测试它,但它不起作用。谁能指出代码中出了什么问题吗?
这是我的 html 页面
<?php
namespace Phppot;
require_once ("lib/MailService.php");
$mailService = new MailService();
if (! empty($_POST['send'])) {
$response = $mailService->sendContactMail($_POST);
}
?>
<html>
<head>
<title>Contact Us Form</title>
<link rel="stylesheet" type="text/css" href="assets/css/style.css" />
</head>
<body>
<div class="form-container">
<form name="frmContact" id="" frmContact"" method="post"
action="" enctype="multipart/form-data"
onsubmit="return validateContactForm()">
<div class="input-row">
<label style="padding-top: 20px;">Name</label> <span
id="userName-info" class="info"></span><br /> <input
type="text" class="input-field" name="userName"
id="userName" />
</div>
<div class="input-row">
<label>Email</label> <span id="userEmail-info"
class="info"></span><br /> <input type="text"
class="input-field" name="userEmail" id="userEmail" />
</div>
<div class="input-row">
<label>Subject</label> <span id="subject-info"
class="info"></span><br /> <input type="text"
class="input-field" name="subject" id="subject" />
</div>
<div class="input-row">
<label>Message</label> <span id="userMessage-info"
class="info"></span><br />
<textarea name="content" id="content"
class="input-field" cols="60" rows="6"></textarea>
</div>
<div>
<input type="submit" name="send" class="btn-submit"
value="Send" />
<div id="statusMessage">
<?php
if (! empty($response)) {
?>
<p
class='<?php echo $response['type']; ?>Message'><?php echo $response['text']; ?></p>
<?php
}
?>
</div>
</div>
</form>
</div>
<script type="text/javascript" src="assets/js/validation.js"></script>
</body>
</html>
这是 get_oauth_token.php
<?php
/**
* PHPMailer - PHP email creation and transport class.
* PHP Version 5.5
* @package PHPMailer
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
/**
* Get an OAuth2 token from an OAuth2 provider.
* * Install this script on your server so that it's accessible
* as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
* e.g.: http://localhost/phpmailer/get_oauth_token.php
* * Ensure dependencies are installed with 'composer install'
* * Set up an app in your Google/Yahoo/Microsoft account
* * Set the script address as the app's redirect URL
* If no refresh token is obtained when running this file,
* revoke access to your app and run the script again.
*/
namespace PHPMailer\PHPMailer;
/**
* Aliases for League Provider Classes
* Make sure you have added these to your composer.json and run `composer install`
* Plenty to choose from here:
* @see http://oauth2-client.thephpleague.com/providers/thirdparty/
*/
//@see https://github.com/thephpleague/oauth2-google
use League\OAuth2\Client\Provider\Google;
//@see https://packagist.org/packages/hayageek/oauth2-yahoo
use Hayageek\OAuth2\Client\Provider\Yahoo;
//@see https://github.com/stevenmaguire/oauth2-microsoft
use Stevenmaguire\OAuth2\Client\Provider\Microsoft;
if (!isset($_GET['code']) && !isset($_GET['provider'])) {
?>
<html>
<body>Select Provider:<br>
<a href='?provider=Google'>Google</a><br>
<a href='?provider=Yahoo'>Yahoo</a><br>
<a href='?provider=Microsoft'>Microsoft/Outlook/Hotmail/Live/Office365</a><br>
</body>
</html>
<?php
exit;
}
require 'vendor/autoload.php';
session_start();
$providerName = '';
if (array_key_exists('provider', $_GET)) {
$providerName = $_GET['provider'];
$_SESSION['provider'] = $providerName;
} elseif (array_key_exists('provider', $_SESSION)) {
$providerName = $_SESSION['provider'];
}
if (!in_array($providerName, ['Google', 'Microsoft', 'Yahoo'])) {
exit('Only Google, Microsoft and Yahoo OAuth2 providers are currently supported in this script.');
}
//These details are obtained by setting up an app in the Google developer console,
//or whichever provider you're using.
$clientId = 'random.apps.googleusercontent.com';
$clientSecret = 'random_key';
//If this automatic URL doesn't work, set it yourself manually to the URL of this script
$redirectUri = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
//$redirectUri = 'http://localhost/PHPMailer/redirect';
$params = [
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'redirectUri' => $redirectUri,
'accessType' => 'offline'
];
$options = [];
$provider = null;
switch ($providerName) {
case 'Google':
$provider = new Google($params);
$options = [
'scope' => [
'https://mail.google.com/'
]
];
break;
case 'Yahoo':
$provider = new Yahoo($params);
break;
case 'Microsoft':
$provider = new Microsoft($params);
$options = [
'scope' => [
'wl.imap',
'wl.offline_access'
]
];
break;
}
if (null === $provider) {
exit('Provider missing');
}
if (!isset($_GET['code'])) {
//If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl($options);
$_SESSION['oauth2state'] = $provider->getState();
header('Location: ' . $authUrl);
exit;
//Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
unset($_SESSION['oauth2state']);
unset($_SESSION['provider']);
exit('Invalid state');
} else {
unset($_SESSION['provider']);
//Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken(
'authorization_code',
[
'code' => $_GET['code']
]
);
//Use this to interact with an API on the users behalf
//Use this to get a new access token if the old one expires
echo 'Refresh Token: ', $token->getRefreshToken();
}
提交表单时,显示错误
致命错误:未捕获错误:在 lib/MailService.php:31 中找不到类“Phppot\SMTP”堆栈跟踪:#0 index.php(7): Phppot\MailService->sendContactMail(Array) #1 {main}抛出在 lib/MailService.php 第 31 行
已编辑
这是我的 MailService.php 文件
<?php
namespace Phppot;
use Phppot\Config;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
class MailService
{
function sendContactMail($postValues)
{
$name = $postValues["userName"];
$email = $postValues["userEmail"];
$subject = $postValues["subject"];
$content = $postValues["content"];
require_once __DIR__ . '/Config.php';
$recipientArray = explode(",", Config::RECIPIENT_EMAIL);
require_once __DIR__ . '/../vendor/autoload.php';
$mail = new PHPMailer(true);
// Comment the following lines of code till $mail->Port to send
// mail using phpmail instead of smtp.
$mail->isSMTP();
//Enable SMTP debugging
//SMTP::DEBUG_OFF = off (for production use)
//SMTP::DEBUG_CLIENT = client messages
//SMTP::DEBUG_SERVER = client and server messages
$mail->SMTPDebug = SMTP::DEBUG_OFF;
//Set the hostname of the mail server
$mail->Host = Config::SMTP_HOST;
//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission
$mail->Port = Config::SMTP_PORT;
//Set the encryption mechanism to use - STARTTLS or SMTPS
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
//Whether to use SMTP authentication
$mail->SMTPAuth = true;
//Set AuthType to use XOAUTH2
$mail->AuthType = 'XOAUTH2';
//Fill in authentication details here
//Either the gmail account owner, or the user that gave consent
$oauthUserEmail = Config::OAUTH_USER_EMAIL;
$clientId = Config::OAUTH_CLIENT_ID;
$clientSecret = Config::OAUTH_SECRET_KEY;
//Obtained by configuring and running get_oauth_token.php
//after setting up an app in Google Developer Console.
$refreshToken = Config::REFRESH_TOKEN;
//Create a new OAuth2 provider instance
$provider = new Google(
[
'clientId' => $clientId,
'clientSecret' => $clientSecret,
]
);
//Pass the OAuth provider instance to PHPMailer
$mail->setOAuth(
new OAuth(
[
'provider' => $provider,
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'refreshToken' => $refreshToken,
'userName' => $oauthUserEmail,
]
)
);
// Recipients
$mail->setFrom(Config::SENDER_EMAIL, $name);
$mail->addReplyTo($email, $name);
$mail->addAddress(Config::RECIPIENT_EMAIL, Config::RECIPIENT_EMAIL);
$mail->Subject = $subject;
$mail->CharSet = PHPMailer::CHARSET_UTF8;
$mail->msgHTML($mailBody);
//Replace the plain text body with one created manually
$mail->AltBody = 'This is a plain-text message body';
if (!$mail->send()) {
$output = json_encode(array('type'=>'error', 'text' => '<b>'.$from.'</b> is invalid.'));
$output = json_encode(array('type'=>'error', 'text' => 'Server error. Please mail vincy@phppot.com'));
} else {
$output = json_encode(array('type'=>'message', 'text' => 'Thank you, I will get back to you shortly.'));
}
return $output;
}
} Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
您遇到命名空间问题。你正在这样做:
然后使用这个:
因为您尚未将 PHPMailer 包中的 SMTP 类名导入到您的命名空间中,所以它将查找名为
Phppot\SMTP的类,该类不存在,因此会出现错误消息。您可以通过添加以下内容来解决此问题:这将使它使用 PHPMailer 中正确的 SMTP 类。
请注意,这里可能存在另一个问题。您已经
use Phppot\Config;,但您已经在Phppot命名空间中,因此将查找名为Phppot\Phppot\Config,可能不存在。如果该类已位于您声明的命名空间中,则不需要为其使用use语句。