php - 我在具有环境的 MVC PHPMailer 上面临持久的“405 Method Not Allowed””,并且我的路由错误
问题描述
我正面临着持久的“405 Method Not Allowed””。在环境中的 MVC PHPMailer 上。
我花了 10 多个小时,试图修复这个错误。我一直在 Stack Overflow 上搜索这个案例,但没有运气。我认为这是文件中的一些 PHPMailer 配置Mail.php
,.env
但所有配置都是正确的。它也可以是其他文件App/routes.php
或public/index.php
.
root/composer.json
:
{
"name": "lucas/simple-mvc",
"authors": [
{
"name": "Lucas Ayabe",
"email": "lucas.akira@gmail.com"
}
],
"autoload": {
"psr-4": {
"App\\": "App/",
"Core\\": "Core/"
},
"files": [
"App/Helpers/view.php",
"App/Helpers/partial.php"
]
},
"require": {
"nikic/fast-route": "^1.3",
"vlucas/phpdotenv": "^5.2",
"phpmailer/phpmailer": "^6.1",
"league/oauth2-google": "^3.0",
"psr/log": "^1.1"
}
}
root/.env
:
MAIL_HOST="br726.hostgator.com.br"
MAIL_PORT=465
MAIL_USER="sacc@thproducoes.com"
MAIL_PASSWORD="mypassword"
MAIL_FROM_NAME="Thiago Silva"
MAIL_FROM_EMAIL="sacc@thproducoes.com"
root/App/Helpers/Mail.php
:
<?php
namespace App\Helpers;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use Exception;
use stdClass;
class Mail
{
private PHPMailer $mail;
private stdClass $data;
private Exception $error;
public function __construct(string $lang = "br")
{
$this->mail = new PHPMailer(true);
$this->data = new stdClass();
$this->mail->isSMTP();
$this->mail->SMTPAuth = true;
$this->mail->Host = $_ENV["MAIL_HOST"];
$this->mail->Port = $_ENV["MAIL_PORT"];
$this->mail->SMTPSecure = "ssl";
$this->mail->Username = $_ENV['MAIL_USER'];
$this->mail->Password = $_ENV['MAIL_PASSWORD'];
$this->mail->isHTML(true);
$this->mail->CharSet = "utf-8";
$this->mail->setLanguage($lang);
}
public function add(
string $subject,
string $body,
string $recipientName,
string $recipientEmail
): self
{
$this->data->subject = $subject;
$this->data->body = $body;
$this->data->recipientName = $recipientName;
$this->data->recipientEmail = $recipientEmail;
return $this;
}
public function attach(string $path, string $filename): self
{
$this->data->attach[$path] = $filename;
return $this;
}
public function send(string $fromName = "", string $fromEmail = ""): bool
{
$fromName = $fromName !== "" ? $fromName : $_ENV['MAIL_FROM_NAME'];
$fromEmail = $fromEmail !== "" ? $fromEmail : $_ENV['MAIL_FROM_EMAIL'];
try {
$this->mail->Subject = $this->data->subject;
$this->mail->msgHTML($this->data->body);
$this->mail->addAddress("sac@thproducoes.com");
$this->mail->addAddress($this->data->recipientEmail, $this->data->recipientName);
$this->mail->setFrom($fromEmail, $fromName);
if (!empty($this->data->attach))
{
foreach ($this->data->attach as $path => $name)
{
$this->mail->addAttachment($path, $name);
}
}
$this->mail->send();
return true;
}
catch (\Exception $exception)
{
$this->error = $exception;
return false;
}
}
public function getError(): ?Exception
{
return $this->error;
}
}
root/App/Views/mail.php
:
<?= partial("templates/header.php") ?>
<form action="mail" method="post">
<div>
<label for="email">E-mail</label>
<input type="email" name="email" id="email">
</div>
<div>
<label for="message">Mensagem</label>
<textarea name="message" id="message"></textarea>
</div>
<button>Enviar</button>
</form>
<?= partial("templates/footer.php")
?>
root/App/routes.php
:
<?php
namespace Source\routes;
use App\Controllers\MailController;
use App\Controllers\PagesController;
use FastRoute\RouteCollector;
return function (RouteCollector $routes)
{
$routes->get('/', [PagesController::class => "index"]);
$routes->get('/mail', [MailController::class => "index"]);
$routes->get('/send', [MailController::class => "send"]);
};
root/Core/App.php
:
<?php
namespace Core;
use FastRoute\Dispatcher as Dispatcher;
class App
{
private Dispatcher $dispatcher;
public function __construct(Dispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
public function run()
{
// Fetch method and URI from somewhere
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER["REQUEST_URI"];
$routeInfo = $this->dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
case Dispatcher::NOT_FOUND:
echo 'NOT FOUND';
break;
case Dispatcher::METHOD_NOT_ALLOWED:
$allowedMethods = $routeInfo[1];
echo '405 Method Not Allowed';
break;
case Dispatcher::FOUND:
$controller = array_key_first($routeInfo[1]);
$action = end($routeInfo[1]);
(new $controller())->$action($routeInfo[2]);
break;
default:
break;
}
}
}
root/Core/Controller.php
:
<?php
namespace Core;
abstract class Controller
{
public function redirect(string $route)
{
header("Location: {$_ENV['BASE_URL']}/$route");
exit();
}
}
root/Core/View.php
:
<?php
namespace Core;
class View
{
private array $vars = [];
private const FORBIDDEN_VAR = "viewTemplaFile";
public function __get($name)
{
return $this->vars[$name];
}
public function __set($name, $value)
{
if ($name === self::FORBIDDEN_VAR) {
throw new \Exception(
"Cannot bind variable named '" . self::FORBIDDEN_VAR . "'"
);
}
$this->vars[$name] = $value;
}
public function load(string $viewTemplateFile)
{
if (array_key_exists(self::FORBIDDEN_VAR, $this->vars)) {
throw new \Exception(
"Cannot bind variable named '" . self::FORBIDDEN_VAR . "'"
);
}
extract($this->vars);
ob_start();
include __DIR__ . "/../App/Views/$viewTemplateFile";
return ob_get_clean();
}
public function render(string $viewTemplateFile)
{
echo $this->load($viewTemplateFile);
}
}
root/public/index.php
:
<?php
use Core\App;
require_once __DIR__ . '/../vendor/autoload.php';
$dotenv = \Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->load();
$routes = require __DIR__ . "/../App/routes.php";
$app = new App(FastRoute\simpleDispatcher($routes));
$app->run();
并且.htaccess
:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?path=$1 [QSA,L]
解决方案
推荐阅读
- javascript - 我们的 await 关键字在 for await of 循环中的行为与普通异步函数中的行为有何不同?
- flutter - FireStore 数据库中的空值......屏幕上总是有这个 CircularProgressIndicator
- typescript - 无效的 Hook Call React(如何分配材质 ui 类)
- c++ - 使类中的函数指针依赖于初始化值
- cassandra - Cassandra Upsert 不适用于每一列
- firebase - Firebase 实时数据库特定安全规则
- python - 如何仅移动带有附件的邮件?
- c# - CreateOrUpdateEntitiesAsync 示例
- html - 我的 scss 文件没有转换成 css 文件
- python-3.x - python中的Fernet,“令牌必须是字节”