Laravel 4 с использованием nikic phpparser: не хватает памяти при отправке электронной почты
Только что узнал, что Laravel использует nikic phpparser изнутри.
Я изменил свой код для отправки электронных писем на одном из условий, и он начал умирать.
Логи PHP показали это:
[Сб. 03.10 21:18:23 2015] [error] [client xx.xx.xx.xx] Неустранимая ошибка PHP: допустимый объем памяти 33554432 байта исчерпан (попытка выделить 1048576 байтов) в /home/yyyy/public_html/vendor/nikic/php-parser/lib/PHPParser/NodeTraverser.php в строке 66, реферер: http://yyyy.com/home
Временно я увеличил память, чтобы решить проблему.
Но я хочу отойти от пластыря.
Я вижу, что функция NodeTraverser выполняет клонирование, это может вызвать проблемы:
protected function traverseNode(PHPParser_Node $node)
{
ini_set('memory_limit', '64M'); // temporary fix
$node = clone $node;
foreach ($node->getSubNodeNames() as $name) {
$subNode =& $node->$name;
if (is_array($subNode)) {
$subNode = $this->traverseArray($subNode);
} elseif ($subNode instanceof PHPParser_Node) {
foreach ($this->visitors as $visitor) {
if (null !== $return = $visitor->enterNode($subNode)) {
$subNode = $return;
}
}
$subNode = $this->traverseNode($subNode);
foreach ($this->visitors as $visitor) {
if (null !== $return = $visitor->leaveNode($subNode)) {
$subNode = $return;
}
}
}
}
return $node;
}
Вот как я отправляю письмо. Это ничем не отличается от других, поэтому я сомневаюсь, что это вызовет проблему:
$this->mailer->queue('emails.forreg',
[
'toName' => $toEmailName,
'fromName' => $user->username,
'site_name' => \Config::get('site_title')
],
function($mail) use($toEmailAddress, $user, $subject_to_send, $toEmailName)
{
$mail->to($toEmailAddress, $toEmailName)
->subject($subject_to_send)
->from('xxx@yyy.com', $user->username);
}
);
Любые идеи о том, как решить эту проблему?
1 ответ
У вас просто крайне низкий предел памяти. PHP ограничение IIRC начинается с 128M по умолчанию. Когда анализатор проходит через это, он создает узел для каждой отдельной части кода. Ничто не исключено, и нет быстрого исправления.
Сегодня память дешевле, чем когда-либо, и вряд ли эта проблема будет решена из-за предстоящего PHP7. Возможно, попробуйте, так как в любом случае, вероятно, она будет занимать меньше памяти.