【问题标题】:PHPMailer not sending email(if construct)PHPMailer 不发送电子邮件(如果构造)
【发布时间】:2020-11-18 19:00:30
【问题描述】:

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

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

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

工作,尽管有错误

致命错误:未捕获的类型错误:传递给 YandexCheckout\Model\Notification\NotificationWaitingForCapture::__construct() 的参数 1 必须是数组类型,给定 null,在 /home/birdyxru/public_html/test/requests.php 中调用第 25 行并在 /home/birdyxru/public_html/test/assets/lib/Model/Notification/NotificationWaitingForCapture.php:72 中定义堆栈跟踪:#0 /home/birdyxru/public_html/test/requests.php(25): YandexCheckout\ Model\Notification\NotificationWaitingForCapture->__construct(NULL) #1 {main} 在第 72 行的 /home/birdyxru/public_html/test/assets/lib/Model/Notification/NotificationWaitingForCapture.php 中抛出

<?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 正确发送,而不是被垃圾邮件过滤器(或其他中介)捕获?考虑到您没有在此处明确设置任何 SMTP 连接信息,后者似乎很可能,并且默认情况下,消息将通过 PHP 的内置 mail() 函数 (source) 发送。这通常是leads to delivery problems
  • 通过邮件 () 发送的信件已正确发送,属于“重要”类别。我无法查看错误,因为该文件只接受 POST 并自行执行某些操作。
  • 为什么接受 POST 请求会阻止您调试脚本...?你能详细说明一下吗?
  • 说实话,如果浏览器中没有显示错误,我只是不知道如何查看错误。
  • 调试是任何语言的核心技能——如果你不熟悉如何调试你的脚本,你真的应该重温一些fundamental documentation on the topic。特别是对于 PHP,Stack Overflow 上还有很多非常有用的资源:@​​987654324@、How do you debug PHP scripts?

标签: php phpmailer


【解决方案1】:

让我们来看看你的错误信息是什么意思:

致命错误:未捕获的 TypeError:传递给 YandexCheckout\Model\Notification\NotificationWaitingForCapture::__construct() 的参数 1 必须是数组类型,给定 null,

参数 1 必须是 数组,但以 null 的形式给出。

什么是“论据 1”?

new NotificationWaitingForCapture($requestBody);

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

PHP Manual states:

如果无法解码 json 或编码数据深度超过递归限制,则返回 NULL。

这是您的问题的原因。

建议修复:

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

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

【讨论】:

  • 错误真的消失了,但是邮件一直没有发送。有错误,因为数组在付款后的某个时刻被转移。
  • @РусланАбдуллоев 您在问题中显示的错误是由数组为 null 引起的。如果电子邮件从未发送过,但其余代码工作正常,那么您需要探究原因,我们无法为您执行此操作。
  • 我完全糊涂了。我目前没有错误,但仍然没有任何效果。我不知道该怎么办。
  • @РусланАбдуллоев 您问题中的第一个代码块使用 PHP mail 函数,您的第二个代码块使用 PHPMailer。你应该使用 PHPMailer。您还应该使用 PHPMailer Exceptions 来捕获异常。还可以使用$mail-&gt;SMTPDebug = 2 输出调试消息以检查一切是否正常工作。
  • 2020-11-20 07:18:17 3 Connection: opening to mail.birdyx.ru:465, timeout=300, options=array() 2020-11-20 07:18:17 3 Connection: opened 2020-11-20 07:18:46 1 CLIENT -&gt; SERVER: QUIT 2020-11-20 07:19:16 1 CLIENT -&gt; SERVER: QUIT 2020-11-20 07:20:18 1 CLIENT -&gt; SERVER: QUIT 2020-11-20 07:22:02 1 CLIENT -&gt; SERVER: QUIT 2020-11-20 07:22:48 1 CLIENT -&gt; SERVER: QUIT 2020-11-20 07:23:19 1 CLIENT -&gt; SERVER: QUIT
【解决方案2】:

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

如果没有更多调试信息,我将大胆猜测问题所在:

你还没有设置你的字符集。

您的内容中有西里尔字符,但您没有更改默认的字符集ISO-8859-1。这很可能会导致错误。

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

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

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

【讨论】:

  • 不幸的是它没有帮助。我猜这里有一个逻辑问题。
猜你喜欢
  • 2016-09-02
  • 1970-01-01
  • 2013-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-19
  • 2021-01-03
相关资源
最近更新 更多