You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复证书邮件发送时的'Trying to access array offset on value of type bool'错误及按钮禁用问题

问题解决:PHPMailer错误与按钮禁用失效

一、解决「Trying to access array offset on value of type bool」错误

你遇到的这个错误根源是PHPMailer的send()方法返回的是布尔值,不是数组,所以你写的$sendEmail["code"]根本不存在,直接访问数组键值就会报错。

修正后的PHP代码(包含正确的错误处理)

<?php 
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception; // 引入Exception类启用异常处理

if(isset($_POST['email_data'])){
    require 'phpmailer/src/Exception.php';
    require 'phpmailer/src/PHPMailer.php';
    require 'phpmailer/src/SMTP.php';
    require 'fpdf/fpdf.php';
    require 'connection.php'; 

    $output='';
    foreach($_POST['email_data'] as $row)
    {
        // 1. 生成证书图片
        $image = imagecreatefrompng('D:/App Projects/Source/idonate/Admin/include/Certificate Template/certificate2.png');
        if(!$image) { // 增加图片加载失败判断
            $output .= "无法加载证书模板图片<br>";
            continue;
        }
        $black = imagecolorallocate($image, 0, 0, 0);
        $font = "D:/App Projects/Source/idonate/Admin/fonts/Roboto-Black.ttf";
        $size = 110;
        $box = imagettfbbox($size, 0, $font, $row['donor_name']);
        $text_width = abs($box[2]) - abs($box[0]);
        $text_height = abs($box[5]) - abs($box[3]);
        $image_width = imagesx($image);
        $image_height = imagesy($image);
        $x = ($image_width - $text_width) / 2;
        $y = ($image_height + $text_height) / 2;

        imagettftext($image, $size, 0, $x, $y, $black, $font, $row['donor_name']);
      
        $file = time();
        $file_path = "download-certificate/".$file.".png";
        imagepng($image, $file_path);
        imagedestroy($image);

        // 2. 生成PDF
        $pdf = new FPDF();   
        $pdf->AddPage('L','A5');
        $pdf->Image($file_path, 0, 0, 210, 150);
        $pdf_content = $pdf->Output("S", 'AcknowledgementReciept.pdf'); // 提前获取PDF字符串

        // 3. 发送邮件(用异常捕获处理错误)
        try {
            $mail = new PHPMailer(true); // 启用异常模式初始化
            $mail->isSMTP();
            $mail->Host = 'smtp.gmail.com';
            $mail->SMTPAuth = true;
            $mail->Username = 'testcdrrmo@gmail.com';
            $mail->Password = 'mlytxekfgplnhsap';
            $mail->SMTPSecure = 'ssl';
            $mail->Port = 465;
        
            $mail->setFrom('testcdrrmo@gmail.com');
            $mail->addAddress($row['donor_email']);
            $mail->isHTML(true);
            $mail->Subject = "Certificate";
            $mail->Body = "This is certificate";
            $mail->addStringAttachment($pdf_content, 'AcknowledgementReciept.pdf', 'base64', 'application/pdf');
            $mail->AltBody = '';
            
            $mail->send();
            // 发送成功后清理临时PNG文件
            unlink($file_path);
        } catch (Exception $e) {
            $output .= "发送给{$row['donor_email']}失败: " . html_entity_decode($mail->ErrorInfo) . "<br>";
            // 失败也清理临时文件
            if(file_exists($file_path)) unlink($file_path);
        }
    }

    echo $output === '' ? 'ok' : $output;
}

关键修正点:

  • 引入Exception类,启用PHPMailer的异常模式,更精准捕获发送错误
  • 移除错误的数组键值访问逻辑,改用$mail->ErrorInfo获取错误详情
  • 增加图片加载失败判断,避免后续代码崩溃
  • 发送完成后删除临时PNG文件,避免服务器空间浪费

二、解决成功发送后按钮无法禁用的问题

你的AJAX代码最后一行强制把disabled设为false,不管发送成功还是失败都会执行,所以成功后按钮仍可点击。

修正后的AJAX代码

$.ajax({
    url: "http://localhost:3000/Admin/include/sendcerti.php",
    method: "POST",
    data: {email_data: email_data},
    beforeSend: function(){
        $('#'+donor_id).html('Sending...');
        $('#' + donor_id).addClass('btn-danger').attr('disabled', true); // 发送前先禁用,防止重复点击
    },
    success: function(data){
        if (data == 'ok')
        {
            $('#' + donor_id).text("Success");
            $('#' + donor_id).removeClass('btn-danger btn-info').addClass('btn-success');
            $('#' + donor_id).attr('disabled', true); // 成功后保持禁用
        }
        else{
            $('#' + donor_id).text(data);
            $('#' + donor_id).removeClass('btn-success').addClass('btn-danger');
            $('#' + donor_id).attr('disabled', false); // 失败后允许重试
        }
    },
    error: function(){
        // 网络错误时的处理
        $('#' + donor_id).text("发送失败");
        $('#' + donor_id).removeClass('btn-success').addClass('btn-danger');
        $('#' + donor_id).attr('disabled', false);
    }
})

关键修正点:

  • beforeSend阶段就禁用按钮,从源头防止重复请求
  • 成功分支里保持disabled为true,锁定按钮
  • 失败/网络错误分支才恢复按钮可点击状态
  • 优化样式切换逻辑,按钮状态更清晰直观

内容的提问来源于stack exchange,提问作者Rico Littawa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 02:10:57