首页 > 解决方案 > 我在具有环境的 MVC PHPMailer 上面临持久的“405 Method Not Allowed””,并且我的路由错误

问题描述

我正面临着持久的“405 Method Not Allowed””。在环境中的 MVC PHPMailer 上。

我花了 10 多个小时,试图修复这个错误。我一直在 Stack Overflow 上搜索这个案例,但没有运气。我认为这是文件中的一些 PHPMailer 配置Mail.php.env但所有配置都是正确的。它也可以是其他文件App/routes.phppublic/index.php.

{
    "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"
    }
}
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"
<?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;
    }
}
<?= 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")
?>
<?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"]);
};
<?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;
        }
    }
}
<?php
namespace Core;

abstract class Controller
{
    public function redirect(string $route)
    {
        header("Location: {$_ENV['BASE_URL']}/$route");
        exit();
    }
}
<?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);
    }
}
<?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]

标签: phpmodel-view-controllerphpmailer

解决方案


推荐阅读