Search code examples
phpphpmailer

PHPMailer not sending email(if construct)


Friends, please explain to me why PHPMailer does not send an email?

He must send a letter after payment. The usual mail() function works, but with PHPMailer I already broke my head. HELP

After payment, this file receives a notification from Yandex that the payment has been made. I made a condition that if the payment is made, then a corresponding letter is sent to the mail.

works, despite the mistake

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);
}
?>

does not work :(

<?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!';
    }
}
?>

I guess the problem is in logic or syntax


Solution

  • Let's explore what your error message says:

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

    Argument 1 must be an array, but is given as null.

    What is "argument 1"?

    new NotificationWaitingForCapture($requestBody);
    

    When a new object is instantiated it runs the __construct method, which the error references, so it is the line mentioned above, so this in turn means that $requestBody is the "Argument 1" and for whatever reason, holds a null value.

    The PHP Manual states:

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

    This is the cause of your issue.

    Suggested Fix:

    You need to check your POST data is populated, rather than simply assume it is, so update your JSON_DECODE to this:

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