PHPMailer 不发送电子邮件(如果构造)

PHPMailer not sending email(if construct)

朋友,请解释一下为什么PHPMailer不发送邮件?

付款后他必须寄信。通常的 mail() 函数可以工作,但是使用 PHPMailer 我已经崩溃了。帮助

付款后,此文件会收到来自 Yandex 的付款已完成的通知。我做了一个条件,如果付款了,那么相应的信件会发到邮箱。

有效,尽管有错误

Fatal error: Uncaught TypeError: Argument 1 passed to YandexCheckout\Model\Notification\NotificationWaitingForCapture::__construct() must be of the type array, null given, called in /home/birdyxru/public_html/test/requests.php on line 25 and defined in /home/birdyxru/public_html/test/assets/lib/Model/Notification/NotificationWaitingForCapture.php:72 Stack trace: #0 /home/birdyxru/public_html/test/requests.php(25): YandexCheckout\Model\Notification\NotificationWaitingForCapture->__construct(NULL) #1 {main} thrown in /home/birdyxru/public_html/test/assets/lib/Model/Notification/NotificationWaitingForCapture.php on line 72

<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
require 'assets/lib/autoload.php';
require 'db/connect.php';

// Получите данные из POST-запроса от Яндекс.Кассы
$source = file_get_contents('php://input');
$requestBody = json_decode($source, true);

// Создайте объект класса уведомлений в зависимости от события
// NotificationSucceeded, NotificationWaitingForCapture,
// NotificationCanceled,  NotificationRefundSucceeded
use YandexCheckout\Model\Notification\NotificationSucceeded;
use YandexCheckout\Model\Notification\NotificationWaitingForCapture;
use YandexCheckout\Model\NotificationEventType;
use YandexCheckout\Model\PaymentStatus;

try {
    $notification = ($requestBody['event'] === NotificationEventType::PAYMENT_SUCCEEDED)
    ? new NotificationSucceeded($requestBody)
    : new NotificationWaitingForCapture($requestBody);
} catch (Exception $e) {
    // Обработка ошибок при неверных данных
}

// Получите объект платежа
$payment = $notification->getObject();
if($payment->getStatus() === PaymentStatus::SUCCEEDED) {
    $payment_id = $payment->getId();
}


if(isset($payment_id)) {
    $email = R::getCell("SELECT `email` FROM `logs` WHERE `payment_id` = '$payment_id'");
    $date = R::getCell("SELECT `date` FROM `logs` WHERE `payment_id` = '$payment_id'");
    $time = R::getCell("SELECT `time` FROM `logs` WHERE `payment_id` = '$payment_id'");
    $report_name = strtok("$email", '@') . ' ' . $date . ' ' . $time;
    // Отправка сообщения
    $mailTo = $email; // Ваш e-mail
    $subject = "На сайте совершен платеж"; // Тема сообщения
    // Сообщение
    $message = "Платеж на сумму: " . $report_name . "<br/>";
    $message .= "Детали платежа: " . $payment->description . "<br/>";
    
    $headers= "MIME-Version: 1.0\r\n";
    $headers .= "Content-type: text/html; charset=utf-8\r\n";
    $headers .= "From: info@site.ru <info@site.ru>\r\n";
    
    mail($mailTo, $subject, $message, $headers);
}
?>

不起作用:(

<?php
require 'assets/lib/autoload.php';
require 'db/connect.php';
require 'mailer/src/PHPMailer.php';

// Получите данные из POST-запроса от Яндекс.Кассы
$source = file_get_contents('php://input');
$requestBody = json_decode($source, true);
// Создайте объект класса уведомлений в зависимости от события
// NotificationSucceeded, NotificationWaitingForCapture,
// NotificationCanceled,  NotificationRefundSucceeded
use YandexCheckout\Model\Notification\NotificationSucceeded;
use YandexCheckout\Model\Notification\NotificationWaitingForCapture;
use YandexCheckout\Model\NotificationEventType;
use YandexCheckout\Model\PaymentStatus;
try {
  $notification = ($requestBody['event'] === NotificationEventType::PAYMENT_SUCCEEDED)
    ? new NotificationSucceeded($requestBody)
    : new NotificationWaitingForCapture($requestBody);
} catch (Exception $e) {
    // Обработка ошибок при неверных данных
}
// Получите объект платежа
$payment = $notification->getObject();
if($payment->getStatus() === PaymentStatus::SUCCEEDED) {
    $payment_id = $payment->getId();
}

use PHPMailer\PHPMailer\PHPMailer;

if(isset($payment_id)) {
    $email = R::getCell("SELECT `email` FROM `logs` WHERE `payment_id` = '$payment_id'");
    $date = R::getCell("SELECT `date` FROM `logs` WHERE `payment_id` = '$payment_id'");
    $time = R::getCell("SELECT `time` FROM `logs` WHERE `payment_id` = '$payment_id'");
    $report_name = strtok("$email", '@') . ' ' . $date . ' ' . $time;
   
    $mail = new PHPMailer();
    //Set who the message is to be sent from
    $mail->setFrom($email_admin, $from_name);
    //Set an alternative reply-to address
    $mail->addReplyTo($email_admin, $from_name);
    //Set who the message is to be sent to
    $mail->addAddress($email);
    //Set the subject line
    $mail->Subject = 'PHPMailer mail() test';
    //Read an HTML message body from an external file, convert referenced images to embedded,
    //convert HTML into a basic plain-text alternative body
    $message = 'Привет ' . $report_name;
    $mail->msgHTML($message);    
    //Replace the plain text body with one created manually
    $mail->AltBody = 'This is a plain-text message body';
    //Attach an image file
    $mail->addAttachment('images/phpmailer_mini.png');

    //send the message, check for errors
    if (!$mail->send()) {
        echo 'Mailer Error: ' . $mail->ErrorInfo;
    } else {
        echo 'Message sent!';
    }
}
?>

我猜问题出在逻辑或语法上

请注意,通过使用 PHPMailer 而不调用 isSMTP(),您也在幕后使用 mail()

在没有更多调试信息的情况下,我将猜测一下哪里出了问题:

您还没有设置字符集。

您的内容中有西里尔字符,但您没有更改默认字符集 ISO-8859-1。这样很容易出错。

假设您使用的是 UTF-8,您需要像这样告诉 PHPMailer:

$mail->CharSet = 'utf-8';

直接使用时它可能与 mail() 一起工作,因为您的 PHP 安装可能设置为使用 UTF-8,但是,PHPMailer 不会将其用作默认,因为它并不总是在所有平台上可用(例如,如果 mbstring 扩展被禁用)。

让我们看看您的错误消息是怎么说的:

Fatal error: Uncaught TypeError: Argument 1 passed to YandexCheckout\Model\Notification\NotificationWaitingForCapture::__construct() must be of the type array, null given,

参数 1 必须是一个 数组,但给出为 null.

什么是“参数 1”?

new NotificationWaitingForCapture($requestBody);

new 对象被实例化时,它运行错误引用的 __construct 方法,所以它是上面提到的行,所以这反过来意味着 $requestBody 是“参数 1”,无论出于何种原因,都具有 null 值。

PHP Manual states:

NULL is returned if the json cannot be decoded or if the encoded data is deeper than the recursion limit.

这就是您遇到问题的原因。

建议的修复:

您需要检查您的 POST 数据是否已填充,而不是简单地假设它已填充,因此请将您的 JSON_DECODE 更新为:

// Получите данные из POST-запроса от Яндекс.Кассы
$source = file_get_contents('php://input');
$requestBody = json_decode($source, true);
if(empty($requestBody)){
   echo "POSTED data is empty! / Опубликованные данные пусты!";
   exit;
}