LARAVEL 7:ErrorException未定义索引

问题描述

我在电子邮件html模板中使用数组索引遇到错误,尽管该索引定义为同一数组中的其他索引。

在电子邮件模板中使用包含索引的索引时会出现问题。据我不使用它的描述如下。

事物始于发送电子邮件的控制器功能

   public function sendToOne(Request $request){
        if ($request->ajax()) {
            $this->validate($request,[
            'user_id'=>'required','infoletter_id'=>'required'
            ]);
            Log::debug('entering sendToOne with user_id '.$request->user_id);
            $infoletter=Infoletter::find($request->infoletter_id);
            $user=User::find( $request->user_id);
            $sender=User::find(1);
            $details=[
                'title'=>$infoletter->title,'body'=>$infoletter->body,'sender'=>$sender,'user'=>$user,];
            $job=(new SendEmailJob($details))->delay($request->delay);
            dispatch($job);
            $duree=$request->delay;
            $minutes=intval(($duree % 3600) / 60);
            $secondes=intval((($duree % 3600) % 60));
            return response()->json(['success'=>'Envoi de l\'infolettre programmé pour '.$user->firstname.' '.$user->familyname .'. L\'envoi aura lieu dans '.$minutes.' minutes et '.$secondes.' secondes.']);
        }
        else{ return 'request is not ajax';}
    }

涉及的数组是$ details,其中我传递了邮件的发件人(用户类)和用户(也包括用户类)。 以$ details数组作为参数调用SendEmailJob。

然后是SendEmailJob

<?PHP

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Mail\InfoletterMail;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
use Carbon\carbon;

class SendEmailJob implements ShouldQueue
{
    use dispatchable,InteractsWithQueue,Queueable,SerializesModels;
    protected $details;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($details)
    {
        $this->details=$details;
    }
    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {  
             Log::debug('entering function handle in SendEmailJob');
             Log::debug($this->details);
            $email = new InfoletterMail($this->details);           
            Mail::to($this->details['user']->email)->send($email);              
     }  
}

其构造函数将details数组作为参数接收,在handle函数中,我们实例化一个InfoletterMail并将其传递给同一数组。 请注意,在此阶段,假设我没有使用索引索引来防止错误,日志(Log :: debug($ this-> details);)会显示存在'sender'索引。

然后是InfoletterMail

<?PHP

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class InfoletterMail extends Mailable
{
    use Queueable,SerializesModels;
    protected $details;
    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($details)
    {
        $this->details=$details;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()

    {
        Log::debug('entering build in InfoletterMail');
        Log::debug($this->details);
        return $this->view('emails.infoletter')->with('details',$this->details);
    }
}

在这个阶段,假设我没有使用内接索引来防止错误,日志(Log :: debug($ this-> details ;;))显示出'sender'索引是正确的。

然后假设我使用隐含索引(“发件人”)来显示电子邮件的视图(emails.infoletter)

<!DOCTYPE html>
<html lang="en">
<head>
    <Meta charset="UTF-8">
    <Meta name="viewport" content="width=device-width,initial-scale=1.0">
    <Meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    @include('emails.inc.intro')
   <p style="text-align: center;"> Bonjour {{$details['user']->firstname}} {{$details['user']->familyname}},</p>
    <div>
        {{$details['body']}}
    </div>
   <p style="text-align: center;"> Bien à vous,</p>
   <p style="text-align: center;">{{$details['sender']->firstname}} {{$details['sender']->familyname}}</p>

</body>
</html>

然后出现错误

未定义索引:发件人(查看: /ORIGINAL-P1/LaraVEL/denentzat/resources/views/emails/infoletter.blade.PHP

我无法确定错误的出处,我需要帮助。

解决方法

我最终做到了。有点难以解释,所以我会尽力而为。

实际上,电子邮件是从查看页面发送的,在发送之前,该页面会先显示给发件人。

用户有不同的按钮,一个发送给所有用户,另一个发送给限制数量的用户,等等。

如果我打算延迟电子邮件的间隔,我会使用jquery脚本遍历用户。在每个循环中,我向控制器中的sendToOne动作发出ajax请求。 控制器响应ajax请求,实例化一个Job(SendMailJob),该Job(SendMailJob)本身实例化一个可邮件(InfoletterMail),该邮件使用带有参数$ details的电子邮件模板,该参数是一个包含“ sender”索引的数组。

如果我以前没有在开头提到的视图中使用相同的电子邮件模板来显示邮件的预览,但是忘记将“发件人”索引添加到我传递的$ details中,那么所有这些都将是正确的对此。 实际上,错误不是由邮件本身创建的,而是由预览创建的。 对于感兴趣的人,此视图带有创建预览的行以及我忘记添加“发件人”索引的行。

$emailview=view('emails.infoletter')->with('details',['title'=>$infoletter->title,'body'=>$infoletter->body,'user'=>$fakeuser,'sender'=>auth()->user()]);
{!!html_entity_decode($emailview)!!}

视图代码

@extends('layouts.bare')


@section('content')

<div class="container mt-4 my-content">
    <div id='messages'>

    </div>  
 

    <div class="d-flex">
                    <a href="/infoletters" class="my-button">Retourner à la liste</a>
                    <a href="" class="my-button">Modifier</a>
                    
            
                <div>
                    {{--below a form with a submit button that will be intercepted by the java script at the bottom of page--}}   
                    {{--The script will trigger ajax requests / one per user--}}
                    {!! Form::open([]) !!}
                        <div class="row post-option-background">
                            <div class="col-md-12" >
                                {{ Form::hidden('infoletter_id',$infoletter->id) }}{{--permetra de retrouver title et body--}}
                                {{ Form::hidden('users',$users )}}{{--permetra de boucler dans jquery--}}
                            
                            </div>
                        </div>
                        {{Form::submit('Envoyer a tous',['class'=>'my-button btn  btn-submit btn-to-all','id'=>'btn-to-all'])}}

                    {!! Form::close() !!}
                </div>
                <div>
                    {{--below a form with a submit button that will be intercepted by the java script at the bottom of page--}}   
                    {{--The script will trigger ajax requests / one per user--}}
                    {!! Form::open([]) !!}
                        <div class="row post-option-background">
                            <div class="col-md-12" >
                                {{ Form::hidden('infoletter_id',$users )}}{{--permetra de boucler dans jquery--}}
                            
                            </div>
                        </div>
                        {{Form::submit('Envoyer au CA',['class'=>'my-button btn  btn-submit btn-to-CA','id'=>'btn-to-CA'])}}

                    {!! Form::close() !!}
                </div>
                <div>
                    {{--below a form with a submit button that will be intercepted by the java script at the bottom of page--}}   
                    {{--The script will trigger ajax requests / one per user--}}
                    {!! Form::open([]) !!}
                        <div class="row post-option-background">
                            <div class="col-md-12" >
                                {{ Form::hidden('infoletter_id',$infoletter->id) }}{{--permetra de retrouver title et body--}}
                                {{ Form::hidden('user_id',Auth::user()->id )}}
                            
                            </div>
                        </div>
                        {{Form::submit('Envoyer à moi-même (test)',['class'=>'my-button btn  btn-submit btn-to-me','id'=>'btn-to-me'])}}

                    {!! Form::close() !!}
                </div>  

    </div>

</div>  
                
<div class="container mt-4 my-content"> 
    
    

    <div class="my-post-body">
        {!!html_entity_decode($emailview)!!}
        
    </div>      
</div>  

<script type="text/javascript">
    $( document ).ready(function() {
        //$('#messages').append('<h1> Le java scirpt fonctionne</h1>');
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),}
        });

        $('#btn-to-all').click(function(e){ 
            e.preventDefault();
            var infoletter_id = $("input[name=infoletter_id]").val();
            var users = $("input[name=users]").val();
            parsed_users=JSON.parse(users);
            var i=0;
            var url='{{ url('infoletters/sendToOne') }}';
            delay=0;
            for (i=0; i<parsed_users.length;i++){
                $.ajax({
                    type:'POST',url:url,data:{user_id:parsed_users[i].id,infoletter_id:infoletter_id,delay:delay},dataType: 'json',success:function(data){
                        $('#messages').prepend('<div class="comments-message" style="margin-bottom:15px;padding:5px;background-color: green; color: white; margin-top:5px;">'+data['success']+'!.</div>');
                    }
                });
                delay=delay+3;
            }   
        });
        $('#btn-to-CA').click(function(e){  
            e.preventDefault();
            var CAMembers=[23,1,4,12,55,19,7,17,18,10,25,5,24];
            var infoletter_id = $("input[name=infoletter_id]").val();
            var users = $("input[name=users]").val();
            parsed_users=JSON.parse(users);
            var i=0;
            var url='{{ url('infoletters/sendToOne') }}';
            delay=0;
            for (i=0; i<parsed_users.length;i++){
                if(CAMembers.includes(parsed_users[i].id)){
                    $.ajax({
                        type:'POST',success:function(data){
                            $('#messages').prepend('<div class="comments-message" style="margin-bottom:15px;padding:5px;background-color: green; color: white; margin-top:5px;">'+data['success']+'!.</div>');
                        }
                    });
                delay=delay+3;

                }
            }   
        });

        $('#btn-to-me').click(function(e){  
            $('#messages').prepend('<div class="comments-message" style="margin-bottom:15px;padding:5px;background-color: green; color: white; margin-top:5px;">Le script fonctionne.</div>');
            e.preventDefault();
            var infoletter_id = $("input[name=infoletter_id]").val();
            var user_id = $("input[name=user_id]").val();
            var url='{{ url('infoletters/sendToOne') }}';
            $.ajax({
                    type:'POST',data:{user_id:user_id,infoletter_id:infoletter_id},success:function(data){
                        $('#messages').prepend('<div class="comments-message" style="margin-bottom:15px;padding:5px;background-color: green; color: white; margin-top:5px;">'+data['success']+'!.</div>');
                    }
                });
                
        });

        
    });
    </script>
@endsection

以及将其他$ details传递给视图的控制器操作,这就是造成问题的原因

  public function view($id)
    {
        //we empty the job tables
        Job::truncate();
        Failed_job::truncate();
        Log::emergency('Entering infoletter@view');
        Log::debug('Entering infoletter@view');
        $infoletter=Infoletter::find($id);
        $users=User::all();
     
        $fakeuser=new User();// to simulate the user in the presentation of the mail in the view
        $fakeuser->firstname='Prénom';
        $fakeuser->familyname='Fake name';
        $emailview=view('emails.infoletter')->with('details','sender'=>auth()->user()]);
        return view('infoletters.view',compact('infoletter','users','emailview'));//here we pass a fake email view as example to bee shown
    }