Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

rbruhn's avatar

Data not being passed to queued job

I'm trying to send a contact email using a queued job but the construct variables are not being passed through. Was wondering if someone can take a look and see what I might be missing. This is Laravel 5.1.19 Controller

public function postContact(ContactFormRequest $request, Config $config)
    {
        $data = [
            'firstName' => $request->get('first_name'),
            'lastName' => $request->get('last_name'),
            'email' => $request->get('email'),
            'message' => $request->get('message'),
            'queue' => $config->get('config.beanstalkd.default')
        ];

        $this->dispatchFromArray(SendContactEmail::class, $data);

        return redirect()->route('home')->with('success', trans('pages.contact_success'));
    }

Job

namespace App\Jobs;

use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Contracts\Config\Repository as Config;

class SendContactEmail extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    public function __construct($firstName, $lastName, $email, $message, $queue)
    {
        $this->firstName = $firstName;
        $this->lastName = $lastName;
        $this->email = $email;
        $this->emailMessage = $message;

        $this->onQueue($queue);
    }

    public function handle(Config $config, Mailer $mailer)
    {
        $emailAddress = $config->get('mail.from.address');
        $emailName = $config->get('mail.from.name');

        $data = [
            'firstName'         => $this->firstName,
            'lastName'         => $this->lastName,
            'email'                => $this->email,
            'emailMessage' => $this->emailMessage,
        ];

        $mailer->send('emails.contact', $data, function ($message) use ($emailAddress, $emailName) {
            $message->to($emailAddress, $emailName)
                ->from($emailAddress, $emailName)
                ->subject(trans('emails.contact_subject'));
        });

        return;
    }

}

The variables passed into the construct never get passed to the handler. If I substitute first name, last name, etc. with actual string values, the job runs and sends an email. If not, I see the job in the queue and then it shows in the failed_jobs table:

{"job":"Illuminate\\Queue\\CallQueuedHandler@call","data":{"command":"O:25:\"App\\Jobs\\SendContactEmail\":3:{s:5:\"queue\";s:11:\"default-new\";s:5:\"delay\";N;s:6:\"\u0000*\u0000job\";N;}"}}

Log

'Undefined property: App\Jobs\SendContactEmail::$firstName'

I'm sending the queue as a variable because I was unable to figure out a way to use dispatchFrom with onQueue. Also could not get information passed if using $this->dispatch.

Doing a dump on the variables passed to the construct shows they are getting there. However, it seems Laravel is not picking them up and passing them to the handler.

Any ideas?

0 likes
7 replies
toniperic's avatar
Level 30

You should declare these variables public.

2 likes
rbruhn's avatar

Thanks, I was just coming back to post that. I figured it out after examining the SerializesModels trait.

tobias@wrklst.art's avatar

I am having the same issue, could you give an example of what needs to be set public? According to https://laracasts.com/series/intermediate-laravel/episodes/11 the variables passed into the constructor need to be protected? Any help would be appreciated.

Here is what I am doing:

<?php

namespace App\Jobs;

use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;

use App\ArtworkImages;
use Storage;
use Uuid;
use Image;

class ImageResizeS3 extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;
    
    protected $data;
    
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->id = $data['id'];
        $this->s3key = $data['s3key'];
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        Storage::makeDirectory('tmp/');
        $tmp_filename = 'tmp/'.Uuid::generate(4)->string.'-id-'.$this->id;
    
...

    }
}

Dispatching the job

$this->dispatch(new ImageResizeS3(array(
            'id' => $ID,
            's3key' => $targetKeyname
        )));
1 like
toniperic's avatar

@tromtv the $data variable in your constructor method is only available and is unique to the local scope (that is, within the constructor itself). It has nothing to do with class property $data.

You should declare class properties $id and $s3key and make them public, likewise


class ImageResizeS3 extends Job implements SelfHandling, ShouldQueue
{
    public $id;
    public $s3key;

    public function __construct($data)
    {
        $this->id = $data['id'];
        $this->s3key = $data['s3key'];
    }
}
nyce's avatar

You don't have to set it public. You can also set it protected (and probably private too). Point is you have to declare it independently of what goes on in the __config() function.

Unfortunately this is not mentioned explicitly in the documentation:

https://laravel.com/docs/5.5/queues#connections-vs-queues

Variables are indeed declared in the code, but the significance is left for the reader to work out himself.

I suppose this is just standard functionality for how PHP works with properties.

Shahrukh4's avatar

Just declare those variable in which you want to recieve data and you can see the dump in terminal.

//Controller
public function func_name(){
    $job = (new SendWelcomeEmail($data))
    dispatch($job);
}


//In Jobs/SendWelcomeEmail
class SendWelcomeEmail implements ShouldQueue
{
     protected $data;

     public function __construct($data)
        {
            $this->data= $data;    
        }

    public function handle(){
        //check your console
        dd($this->data);
    }
}

Please or to participate in this conversation.