首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP SwiftMailer StringReplacementFilter bug解决方案

PHP SwiftMailer StringReplacementFilter bug解决方案
EN

Stack Overflow用户
提问于 2016-12-22 22:27:03
回答 1查看 115关注 0票数 1

试图实现一个临时解决方案来处理这个奇怪的SwiftMailer错误:

https://github.com/swiftmailer/swiftmailer/issues/762

当读取长度正好为n*8192字节(n >= 1)的文件时,$bytes的最后一个>值是一个空字符串,它会触发错误。

@raffomania对GitHub的评论:

我们发现,AbstractFilterableInputStream.write的以下适应将为我们解决问题:

代码语言:javascript
复制
public function write($bytes)
{
    $this->_writeBuffer .= $bytes;
    if (empty($this->_writeBuffer)) {
        return;
    }
    foreach ($this->_filters as $filter) {
        if ($filter->shouldBuffer($this->_writeBuffer)) {
            return;
        }
    }
    $this->_doWrite($this->_writeBuffer);

    return ++$this->_sequence;
}

我想扩展AbstractFilterableInputStream类,并在AbstractFilterableInputStream被SwiftMailer调用时调用这个修改过的写方法。

我在使用Laravel框架。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-23 02:44:36

解决这一问题的最佳方法是将“迅捷邮件”分叉并修复,并使用自己的分叉版本的“迅捷邮件”。但是,如果您不想这样做,这个修复是相当长的,但它应该可以工作。试试看。如果有什么问题,请告诉我。

创建app/Mail/CustomFileByteStream.php:--这是您自己的write版本。

代码语言:javascript
复制
<?php

namespace App\Mail;

/**
 * Allows reading and writing of bytes to and from a file.
 *
 * @author Chris Corbyn
 */
class CustomFileByteStream extends \Swift_ByteStream_FileByteStream
{
    public function write($bytes)
    {
        $this->_writeBuffer .= $bytes;
        if (empty($this->_writeBuffer)) {
            return;
        }
        foreach ($this->_filters as $filter) {
            if ($filter->shouldBuffer($this->_writeBuffer)) {
                return;
            }
        }
        $this->_doWrite($this->_writeBuffer);

        return ++$this->_sequence;
    }
}

创建app/Mail/CustomSwiftAttachment.php:,以便使用自定义FileByteStream

代码语言:javascript
复制
<?php

namespace App\Mail;

/**
 * Attachment class for attaching files to a {@link Swift_Mime_Message}.
 *
 * @author Chris Corbyn
 */
class CustomSwiftAttachment extends \Swift_Attachment
{
    /**
     * Create a new Attachment from a filesystem path.
     *
     * @param string $path
     * @param string $contentType optional
     *
     * @return Swift_Mime_Attachment
     */
    public static function fromPath($path, $contentType = null)
    {
        return self::newInstance()->setFile(
            new CustomFileByteStream($path),
            $contentType
            );
    }
}

创建app/Mail/CustomSwiftImage.php:,以便使用自定义FileByteStream

代码语言:javascript
复制
<?php

namespace App\Mail;

/**
 * An image, embedded in a multipart message.
 *
 * @author Chris Corbyn
 */
class CustomSwiftImage extends \Swift_Image
{
    /**
     * Create a new Image from a filesystem path.
     *
     * @param string $path
     *
     * @return Swift_Image
     */
    public static function fromPath($path)
    {
        $image = self::newInstance()->setFile(
            new CustomFileByteStream($path)
            );

        return $image;
    }
}

创建app/Mail/Message.php:,以便使用您自己的自定义Swift_ImageSwift_Attachment

代码语言:javascript
复制
<?php

namespace App\Mail;

use Illuminate\Mail\Message as DefaultMessage;

class Message extends DefaultMessage
{
    /**
     * Create a Swift Attachment instance.
     *
     * @param  string  $file
     * @return CustomSwiftAttachment
     */
    protected function createAttachmentFromPath($file)
    {
        return CustomSwiftAttachment::fromPath($file);
    }

    /**
     * Embed a file in the message and get the CID.
     *
     * @param  string  $file
     * @return string
     */
    public function embed($file)
    {
        return $this->swift->embed(CustomSwiftImage::fromPath($file));
    }
}

创建app/Mail/Mailer.php:,以便使用自定义的Message

代码语言:javascript
复制
<?php

namespace App\Mail;

use Swift_Message;
use Illuminate\Mail\Mailer as DefaultMailer;

class Mailer extends DefaultMailer
{
    /**
     * Create a new message instance. Notice this is complete replacement of parent's version.
     * We uses our own "Message" class instead of theirs.
     *
     * @return \Illuminate\Mail\Message
     */
    protected function createMessage()
    {
        $message = new Message(new Swift_Message);

        // If a global from address has been specified we will set it on every message
        // instances so the developer does not have to repeat themselves every time
        // they create a new message. We will just go ahead and push the address.
        if (! empty($this->from['address'])) {
            $message->from($this->from['address'], $this->from['name']);
        }

        return $message;
    }
}

创建app/Mail/MailServiceProvider.php:,以便使用自定义的Mailer

代码语言:javascript
复制
<?php

namespace App\Mail;

use Illuminate\Mail\MailServiceProvider as DefaultMailServiceProvider;
use App\Mail\Mailer;

/**
 * This mail service provider is almost identical with the illuminate version, with the exception that
 * we are hijacking with our own Message class
 */
class MailServiceProvider extends DefaultMailServiceProvider
{
    /**
     * Complete replacement of parent register class so we can
     * overwrite the use of mailer class. Notice the "Mailer" class is points to our own
     * version of mailer, so we can hijack the message class.
     *
     * @return void
     */
    public function register()
    {
        $this->registerSwiftMailer();

        $this->app->singleton('mailer', function ($app) {
            // Once we have create the mailer instance, we will set a container instance
            // on the mailer. This allows us to resolve mailer classes via containers
            // for maximum testability on said classes instead of passing Closures.
            $mailer = new Mailer(
                $app['view'], $app['swift.mailer'], $app['events']
            );

            $this->setMailerDependencies($mailer, $app);

            // If a "from" address is set, we will set it on the mailer so that all mail
            // messages sent by the applications will utilize the same "from" address
            // on each one, which makes the developer's life a lot more convenient.
            $from = $app['config']['mail.from'];

            if (is_array($from) && isset($from['address'])) {
                $mailer->alwaysFrom($from['address'], $from['name']);
            }

            $to = $app['config']['mail.to'];

            if (is_array($to) && isset($to['address'])) {
                $mailer->alwaysTo($to['address'], $to['name']);
            }

            return $mailer;
        });
    }
}

编辑config/app.php 7.

  • 注释掉Illuminate\Mail\MailServiceProvider::class,
  • 将下面的代码添加到App\Mail\MailServiceProvider::class,上的行下面

因此,这将使用您的自定义MailServiceProvider。在任何时候,如果您想要恢复这个,只需删除上面的所有文件,并反转此编辑。

呼叫顺序:

所以给你。这应该会劫持MailServiceProvider以使用您自己的自定义Swift_ByteStream_FileByteStream。希望没有打字!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41292545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档