Laravel邮件错误

Not long ago I started receiving this strange error with mail sending in my Laravel application, error is:

ErrorException in EsmtpTransport.php line 55:
Argument 1 passed to Swift_Transport_EsmtpTransport::__construct() must implement interface Swift_Transport_IoBuffer, none given

Interesting thing is that my mailing system worked just fine for about a year, nothing has been updated (just server and domain paid again few weeks back), so I presume that code isn't the problem, I double checked information in mail authentication system, those are right too.

I followed exception stack trace, and found that in Swift_SmtpTransport::__construct() parameters are sent right, but from there Swift_EsmtpTransport::__construct() is called without parameters (which is actually error shown)

Also I updated all my libraries (with "composer update" command). I have no idea what can be wrong, and couldn't find anything that helps online, so any help will be great

Current versions are:

  • "laravel/framework": "5.2.*" // from "composer.json"
  • "swiftmailer/swiftmailer": "~5.1" (v5.4.6 after update) // from "laravel/framework/composer.json"

--- Edit ---
I found somewhere that this is some kind of loading (Dependency Injection) problem, so I executed this line of code:

var_dump(Swift_DependencyContainer::getInstance()->createDependenciesFor('transport.smtp'));

And got this as result array(0) { }

If anyone is interested, I found answer (with friends help). Problem is incompatibility with PHP version, apparently SwiftMailer library doesn't work on newer versions of PHP (>5.5.9, maybe few versions up, not sure from which version it start failing).

Fail is because of some auto-loading conflicts. Solution to this problem is reverting from lazy load to preload, that will slow down a little bit response time, but in most cases you won't even notice that (in my case, I don't see any decline in performance).

Concrete solution:
Find %APP%/vendor/swiftmailer/swiftmailer/lib/swift_requied.php and change it to look like this

<?php

/*
 * This file is part of SwiftMailer.
 * (c) 2004-2009 Chris Corbyn
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/*
 * Autoloader and dependency injection initialization for Swift Mailer.
 */

if (class_exists('Swift', false)) {
    return;
}

// Load Swift utility class
require __DIR__.'/classes/Swift.php';

if (!function_exists('_swiftmailer_init')) {
    function _swiftmailer_init()
    {
        require __DIR__.'/swift_init.php';
    }
}

// Start the autoloader and lazy-load the init script to set up dependency injection
// Swift::registerAutoload('_swiftmailer_init');

_swiftmailer_init();

Difference is in last line, Swift::registerAutoload('_swiftmailer_init'); is commented out, and _swiftmailer_init method is called directly.

Hope this helps someone, because I lost about 2 days trying to fix this.