【问题标题】:Mail dynamically created .ics file attachment unable to open file for reading邮件动态创建的 .ics 文件附件无法打开文件进行阅读
【发布时间】:2017-04-07 03:42:27
【问题描述】:

环境:
- Laravel 5.3

案例:
有关“事件”的邮件,包括带有 iCalendar 文件 (.ics) 的附件。正在使用PHP 生成ics 文件。

问题:
在发送邮件时with ics 文件 Laravel 返回以下错误:

Swift_IoException 在 FileByteStream.php 第 144 行: 无法打开文件读取 [/storage/app/public/events/eventname.ics]

在没有邮件的情况下使用生成的文件似乎很好。该事件被添加到日历中,因此文件不会损坏。调试时(路径上的dd)文件正在返回,因此文件夹/访问权限似乎也很好。

代码:

// Build mail
public function build()
{
    $event = $this->createEvent($this->data[2]->planned_at, $this->data[2]->subject, $this->data[2]->content);

    return $this->view('emails.template')
        ->from('info@stackoverflow.nl', 'Stackoverflow')->subject($this->data[2]->subject)
        ->with([
            'token' => $this->data[0],
            'email' => $this->data[1],
            'mail' => $this->data[2],
            'sponsors' => $this->data[3],
            'name' => $this->data[4],

        ])
        ->attach(Storage::url('app/public/events/' . $this->data[2]->subject . '.ics'), [
            'as' => $this->data[2]->subject . '.ics',
            'mime' => 'calendar/event',
        ]);
}

// Build ics file
static function createEvent($date, $subject, $content)
{
    $dateTimeArr = explode(' ', $date);
    $newDate = $dateTimeArr[0];
    $dateArr = explode('-', $newDate);
    $newDate = $dateArr[0] . $dateArr[1] . $dateArr[2] . '-' . $dateTimeArr[1];
    $date = substr($newDate, 0, -9);

    $startTime = str_replace(":", "", substr($newDate, 9, -3));

    $strip = str_replace("\r", "", strip_tags($content));
    $desc = str_replace("\n", "", $strip);

    // ICS
    $mail[0] = "BEGIN:VCALENDAR";
    $mail[1] = "-//WEBSITE v1.0//NL";
    $mail[2] = "VERSION:2.0";
    $mail[3] = "METHOD:PUBLISH";
    $mail[4] = "BEGIN:VCALENDAR";
    $mail[5] = "DTSTART:" . $date . "T" . $startTime . "00Z";
    $mail[6] = "DTEND:" . $date . "T" . $startTime . "00Z";
    $mail[7] = "DTSTAMP:" . gmdate('Ymd') . 'T' . gmdate('His') . "Z";
    $mail[8] = "UID:" . md5(uniqid(mt_rand(), true));
    $mail[9] = "ORGANIZER;" . "Stackoverflow";
    $mail[10] = "CREATED:" . $date . "T" . $startTime . "00Z";
    $mail[11] = "DESCRIPTION:" . $desc;
    $mail[12] = "LAST-MODIFIED:" . $date . "T" . $startTime . "00Z";
    $mail[13] = "LOCATION:" . "";
    $mail[14] = "SEQUENCE:0";
    $mail[15] = "STATUS:CONFIRMED";
    $mail[16] = "SUMMARY:" . "";
    $mail[17] = "TRANSP:OPAQUE";
    $mail[18] = "END:VEVENT";
    $mail[19] = "END:VCALENDAR";

    //set correct content-type-header
    $filename = $subject . '.ics';
    $mail = implode("\r\n", $mail);

    header("text/calendar");

    Storage::put('public/events/' . $filename , $mail);
}

【问题讨论】:

  • 可能是权限问题,服务器进程用户是否有权访问 /storage/app/public/events/ 文件夹?
  • 在“dd”存储路径时,文件被返回,因此文件被正确访问
  • 如果我的回答解决了您的问题,请将其标记为已接受

标签: laravel email laravel-5 icalendar swiftmailer


【解决方案1】:

许多类似的票证建议您需要将真实路径传递给 swiftmailer。

类似这样的:

public function build()
{
$event = $this->createEvent($this->data[2]->planned_at, $this->data[2]->subject, $this->data[2]->content);
$path=realpath('app/public/events/' . $this->data[2]->subject . '.ics');
return $this->view('emails.template')
    ->from('info@stackoverflow.nl', 'Stackoverflow')->subject($this->data[2]->subject)
    ->with([
        'token' => $this->data[0],
        'email' => $this->data[1],
        'mail' => $this->data[2],
        'sponsors' => $this->data[3],
        'name' => $this->data[4],

    ])
    ->attach($path), [
        'as' => $this->data[2]->subject . '.ics',
        'mime' => 'calendar/event',
    ]);
}

https://laracasts.com/discuss/channels/laravel/unable-to-open-file-for-reading-swift-ioexception

PHP, Swift-mailer problem

Retrieving a file name to attach to an email with SwiftMailer and PHP

【讨论】:

  • Realpath 总是返回 false,尝试了多个不同的路径作为参数
  • 这是假设你的文件系统设置正确laravel.com/docs/5.3/filesystemRemember, if you are using the local driver, all files that should be publicly accessible should be placed in the storage/app/public directory. Furthermore, you should create a symbolic link at public/storage which points to the storage/app/public directory.
  • 我知道,并且该文件已找到。但。 Realpath 每次都返回 false。
  • Realpath 使用文件系统路径 - 您必须将完整路径传递给它 stackoverflow.com/questions/7462006/…
  • 好吧,明白了。现在可以了。有没有办法防止使用真实路径?否则每次我们从虚拟机切换到实时服务器时都需要更改路径等等?
猜你喜欢
  • 2018-08-25
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多