我正在尝试发送附带pdf的电子邮件。 我有一个Command发送大量的电子邮件和swiftmailer配置文件假脱机但我有这个错误:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 523800 bytes) in .....vendor/tcpdf/tcpdf.php on line 4989
我的swiftmailer配置是:
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
spool: { type: file, path: "%kernel.root_dir%/spool" }
我的命令是:
class EnviarJustificanteCommand extends ContainerAwareCommand {
protected function configure()
{
$this
->setName('preinscripciones:enviar')
->setDescription('Enviar Justificantes')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getContainer()->get('doctrine')->getEntityManager();
$textoMailPreinscripcion = "......";
//find alumnos
$preinscritos = $em->getRepository('BackendAlumnosBundle:Historial')->findAlumnosEnviarJustificante();
foreach ($preinscritos as $key => $alumno) {
if ($alumno->getEmail() != null) {
$message = \Swift_Message::newInstance()
->setSubject('Preinscripción realizada')
->setFrom(array($this->container->getParameter('fromemail.contact') => '........'))
->setReplyTo($this->container->getParameter('replyto.email'))
->setTo($alumno->getEmail())
->setBody($textoMailPreinscripcion);
// Create your file contents in the normal way, but don't write them to disk
$data = $this->imprmirJustificantePreinscripcionPDF($escuela, $alumno, true);
// Create the attachment with your data
$attachment = \Swift_Attachment::newInstance($data, 'JustificantePreinscripcion.pdf', 'application/pdf');
// Attach it to the message
$message->attach($attachment);
$this->get('mailer')->send($message);
}
//set flag to 0 as sent
foreach ($alumno->getHistorial() as $key => $historial) {
$historial->setEnviarJustificante(false);
$em->persist($alumno);
}
}
$em->flush();
}
}
我不知道为什么我将swiftmailer配置为内存耗尽的类型文件。一些线索?
提前致谢!
答案 0 :(得分:1)
Swift_Attachment::newInstance()
接受数据作为String或实现Swift_OutputByteStream
的流。
你正在使用一个String,在你的情况下,它对于内存来说太大了。 (Swift执行base64编码,这会占用更多内存)
您需要将数据作为Stream传递,从而实现增量读取。
在您的情况下,您可以通过将数据写入磁盘,然后获取文件资源句柄并将其包装在包装类中来完成此操作。
Wrapper类的一个示例是:
class AttachmentStream implements Swift_OutputByteStream
{
protected $resource;
public function __construct($resource)
{
$this->resource = $resource;
}
public function read($length)
{
$string = fread($this->resource, $length);
if(false === $string){
throw new Swift_IoException('Unable to read from stream');
}
return (0 === strlen($string)) ? false : $string;
}
public function setReadPointer($byteOffset)
{
return 0 === fseek($this->resource,$byteOffset);
}
}
然后您可以将其称为:
...
$fp = fopen($file,$mode);
$stream = new AttachmentStream($fp);
$filename = 'JustificantePreinscripcion.pdf';
$contentType = 'application/pdf';
$attach = Swift_Attachment::newInstance($stream,$filename,$contentType);
答案 1 :(得分:-1)
在尝试生成PDF文件时,看起来它在TCPD中死亡。不太令人惊讶; TCPDF非常苛刻。试试http://knpbundles.com/KnpLabs/KnpSnappyBundle包,它使用wkhtmltopdf(http://wkhtmltopdf.org/)。应该快得多,并且不太可能遇到内存限制。