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

idcreatv's avatar

Sending email via command results in local.ERROR: strtolower(): Passing null to parameter #1 ($string)

I'm coding up a command which runs daily and checks if any courses are taking place on that day. If there is, it grabs the emails of the attendees and sends them an email reminder.

I've coded everything up and run it in a normal view and it runs perfectly, no errors or anything showing up in the error log and I receive the emails.

Now I've built my command, I've dropped my code in (along with dependencies) and logged the output using info(). I can see its pulling the course and attendee emails (which are popped into an array and used in the BCC of the mail message).

When I comment out the info() and use my Mail:: sender, I get a really long error list which starts off with this:

[2022-09-12 16:39:00] local.ERROR: strtolower(): Passing null to parameter #1 ($string) of type string is deprecated {"exception":"[object] (ErrorException(code: 0): strtolower(): Passing null to parameter #1 ($string) of type string is deprecated

I'm not using strtolower() anywhere in my code so I'm guessing this could have something to do with SwiftMailer(?), but I may also have run into something I need to work around as I've not really coded commands before.

Can anyone shed any light onto why this happens?

0 likes
21 replies
Sinnbeck's avatar

Run the command with -vvv to get the full stack trace. It should lead you to where in your code originates. Tracking down the error based strtolower in all of laravel + all dependencies is a needle in a haystack

idcreatv's avatar

Hi @sinnbeck, this is what I get when I run php artisan schedule:work -vvv :


[2022-09-12 17:05:00] local.ERROR: strtolower(): Passing null to parameter #1 ($string) of type string is deprecated {"exception":"[object] (ErrorException(code: 0): strtolower(): Passing null to parameter #1 ($string) of type string is deprecated at /home/USER/WEBSITE.co.uk/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php:144)
[stacktrace]
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(8192, 'strtolower(): P...', '/home/USER/p...', 144)
#1 /home/USER/WEBSITE.co.uk/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php(144): strtolower(NULL)
#2 /home/USER/WEBSITE.co.uk/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php(43): Swift_Transport_EsmtpTransport->setEncryption(NULL)
#3 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(194): Swift_SmtpTransport->__construct('mail.WEBSITE.c...', '465')
#4 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(178): Illuminate\Mail\MailManager->createSmtpTransport(Array)
#5 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(152): Illuminate\Mail\MailManager->createTransport(Array)
#6 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(120): Illuminate\Mail\MailManager->createSwiftMailer(Array)
#7 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(95): Illuminate\Mail\MailManager->resolve('smtp')
#8 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(73): Illuminate\Mail\MailManager->get('smtp')
#9 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php(550): Illuminate\Mail\MailManager->mailer()
#10 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(261): Illuminate\Mail\MailManager->__call('to', Array)
#11 /home/USER/WEBSITE.co.uk/app/Console/Commands/DailyCourseReminder.php(100): Illuminate\Support\Facades\Facade::__callStatic('to', Array)
#12 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): App\Console\Commands\DailyCourseReminder->handle()
#13 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Container/Util.php(40): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#14 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#15 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#16 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Container/Container.php(653): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#17 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Console/Command.php(136): Illuminate\Container\Container->call(Array)
#18 /home/USER/WEBSITE.co.uk/vendor/symfony/console/Command/Command.php(299): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#19 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Console/Command.php(121): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#20 /home/USER/WEBSITE.co.uk/vendor/symfony/console/Application.php(978): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#21 /home/USER/WEBSITE.co.uk/vendor/symfony/console/Application.php(295): Symfony\Component\Console\Application->doRunCommand(Object(App\Console\Commands\DailyCourseReminder), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#22 /home/USER/WEBSITE.co.uk/vendor/symfony/console/Application.php(167): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#23 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Console/Application.php(94): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#24 /home/USER/WEBSITE.co.uk/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(129): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#25 /home/USER/WEBSITE.co.uk/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#26 {main}
"} 

Does this help?

idcreatv's avatar

Oh, there's a reference to

DailyCourseReminder.php(100)

On line 100 its just

 Mail::to($email_recipients)

which is an array, but I've changed it to my own email address and the error is the same.

idcreatv's avatar

@Sinnbeck Sure, here you go. I use a generic emailer and just construct the message in the controller (or the command in this case) so I can use the same format when creating new mailers are overkill.

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

use Carbon\Carbon;
use Mail;

use App\Models\Course;
use App\Models\Coursesettings;
use App\Mail\GenericEmail;

class DailyCourseReminder extends Command
{
  /**
   * The name and signature of the console command.
   *
   * @var string
   */
  protected $signature = 'daily:reminder';

  /**
   * The console command description.
   *
   * @var string
   */
  protected $description = 'Command description';

  /**
   * Create a new command instance.
   *
   * @return void
   */
  public function __construct()
  {
    parent::__construct();
  }

  /**
   * Execute the console command.
   *
   * @return int
   */
  public function handle()
  {
    $email_recipients = [];
    $courses = Course::with('bookings')->where('start_date', Carbon::today())->get();
    foreach ($courses as $course) {
      $bookings = $course->bookings;
      // Grab the bookings
      foreach ($bookings as $booking) {
        // Grab the attendees
        foreach (json_decode($booking->attendees) as $attendee) {
          $email = $attendee->email;
          if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
            array_push($email_recipients, $email);
          }
        }
      }
    }
    // Send the emails
    if ($email_recipients != null) {
      // Grab the Coursesettings key => value pairs
      $settings = Coursesettings::orderby('key', 'asc')
      ->where('key', 'email_attendee_booking_confirmation')
      ->pluck('value', 'key')->toArray();
      // Course type
      if ($course->type == 0) {
        $course_type = 'physical';
      } else {
        $course_type = 'virtual';
      }
      // Set subject
      $subject = 'Reminder: You are enrolled on a course for today';
      // Intro text
      $intro_text = 'Hello, this email is to remind you that you are booked on the following course for today:';
      // Message
      $message_body = $settings['email_attendee_booking_confirmation'];
      // Shortcodes to change
      $message_body = str_replace('[COURSENAME_HERE]', $course->coursename->name, $message_body);
      $message_body = str_replace('[STARTDATE_HERE]', Carbon::parse($course->start_date)->format('d/m/Y'), $message_body);
      $message_body = str_replace('[STARTTIME_HERE]', $course->start_time, $message_body);
      $message_body = str_replace('[ENDTIME_HERE]', $course->end_time, $message_body);
      $message_body = str_replace('[COURSETYPE_HERE]', $course_type, $message_body);

      $message = [
       'intro' => $intro_text,
       'message_body' => $message_body,
       'show_panel' => 'no',
       'panel_body' => 'PANEL_BODY',
       'show_button' => 'no',
       'button_label' => 'BUTTON_LABEL',
       'button_url' => url(''),
       ];

      Mail::to($email_recipients)
       ->send(new GenericEmail($message, $subject)); // End of attendee email
    // info($email_recipients);
    return 0;
    }
  }
}
idcreatv's avatar

@Sinnbeck I did see that earlier but its strange as I have settings for all these…

MAIL_MAILER=smtp
MAIL_HOST=mail.…….co.uk
MAIL_PORT=465
MAIL_USERNAME=…@….co.uk
MAIL_PASSWORD=XXXXXXX
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS="…@….co.uk"
MAIL_FROM_NAME="${APP_NAME}"

I've sent quite a few emails while testing today so I can't see it being those settings in the wrong.

idcreatv's avatar

@Sinnbeck GenericEmail.php…

<?php

namespace App\Mail;

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

class GenericEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($message, $subject)
    {
        $this->message = $message;
        $this->subject = $subject;
    }

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

        return $this->markdown('emails.generic.generic-email')
        ->with('message', $this->message)
        ->subject($this->subject);

    }
}

Generic-email blade file…

@component('mail::message')
# {!! $message['intro'] !!}


{!! $message['message_body'] !!}

@if ($message['show_panel'] == 'yes')
@component('mail::panel')
{!! $message['panel_body'] !!}
@endcomponent
@endif

@if ($message['show_button'] == 'yes')
  @component('mail::button', ['url' => $message['button_url']])
  {{ $message['button_label'] }}
  @endcomponent
@endif

@if (isset($message['attachments']))
@foreach ($message['attachments'] as $attachment)
  @component('mail::button', ['url' => url($attachment['URL'])])
  {{ $attachment['button_name'] }}
  @endcomponent
  @endforeach
@endif

@endcomponent
idcreatv's avatar

@Sinnbeck I copied the code from that file and dropped it into my file in vendor/swiftmailer… etc.

I've cleared the caches.

There's no long error any more, however the result of the command is this…

[2022-09-12T19:25:00+01:00] Execution #1 output:
No scheduled commands are ready to run.

I've tried commenting my mailer out and just running a simple log('TEST'); but its not hitting the log file now. :/

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@idcreatv ok that sounds like a bad idea. Better to actually solve the problem (like updating your depencies to get the newest version)

That there is no scheduled tasks isn't related to the problem

1 like
idcreatv's avatar

@Sinnbeck Okay, I’ll revert it and update composer in the morning to see if that solves it. Will update this thread as soon as I’ve tried it. 👍

idcreatv's avatar

@sinnbeck Morning. I replaced the original vendor files with my backup version and ran composer update. That seemed to fix things and I was able to fire off a reminder email :).

I stopped the schedule and then restarted it (its set to run every minute) just to make sure its working but then I get the 'No scheduled commands are ready to run' message in console, even though it should still run (ultimately it will run once per day, its just every minute for testing).

Is there anything which needs to be reset to make it run the same command?

Sinnbeck's avatar

@idcreatv Sounds good! Please mark this thread as solved, and create a new one in regards to your schedule. That it failed to send due to that package, isnt really related to scheduling :)

Sinnbeck's avatar

/home/USER/WEBSITE.co.uk/app/Console/Commands/DailyCourseReminder.php(100):

Please or to participate in this conversation.