Regex.320

更新(2015年7月)

这与...有关 DOT-DEB.,这保留了使用旧的PCRE库。这已由Guillaume Plessis直接固定在包装中,现在正好工作。

I’如果这有助于任何情况,请保持此帖子,但这应该是’t be useful anymore.

WordPress不发送邮件,而PHP 5.6.9确实如此

我昨天失去了很多时间,有一些明显的悖论:WordPress WORN’T发送邮件,而PHP为它配置了很好。

如果你想要快速修复

这是一个正则表达式问题。在里面 PHPMailer. 类,在实际发送之前,有一个正则表达式验证电子邮件。这个正则表达式没有’T使用PRCE 8.37编译,而它用于使用以前使用的PHP(8.34)的先前PRCE库。正则表达式失败,邮件被拒绝发送。

作为快速修复,我使用此本机函数,而是正则函数。根据评论,它不如,但足够了。

return filter_var($address, FILTER_VALIDATE_EMAIL);

长话长长

当此版本在5月份提供时,我们将服务器升级到运行PHP 5.6.9。所有服务都在新版本上运行罚款。我们感受到了一些关于电子邮件的怪癖没有交付,但这’非常常见的邮件:没什么特别的担心。

与exakat的Beta版本明显,在下载前请求电子邮件。现在,该邮件未被捕获,并且在网站上显示了一个红色错误消息。一切都在正常工作,直到那时,并严格检查了功能。我们花了很长时间才能将其链接到PHP版本。

像往常一样,第一个嫌疑人是WordPress插件及其配置。所以,我们更新了任何滞后的东西:它没有’改变一件事。它很明显电子邮件没有’留下服务器,这是邮件的奇怪’t甚至记录在日志中。

所以,下一个嫌疑人是邮件和黑名单。重新安装导致得出的结论是PHP将正确发送邮件。在一个简单的脚本中使用mail()正在按预期工作,但仍然没有歌词。

遵循错误日志

我们尝试了许多WP插头,特别是WP邮件记录并检查电子邮件。后者不会’T工作,就像PHP的任何电子邮件功能一样:它默默地失败了。这令人沮丧,但这是一小部分信息。前者实际上记录了电子邮件活动,这导致我们认为问题在WP_MAIL和Sendmail之间。现在,这是一个很好的提示:下一步是检查PHP错误日志,并在那里是:

PHP Warning: preg_match(): Compilation failed: internal error: 未找到之前检查的引用子模式 at offset 728 in /var/www/wp-includes/class-phpmailer.php

错误是 巨大的正则表达式,用于验证电子邮件地址:

<?php
//....
                return (bool)preg_match(
                    '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
                    '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
                    '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
                    '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
                    '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
                    '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
                    '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
                    '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
                    '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
                    $address
                );
                break;
//....
?>

这看起来很可疑,但一个细节错了: class-phpmailer.php. 在WordPress中至少有一岁,并且尚未触及很长一段时间。为什么这一正面表达突然失败了?

当然,当相同的旧代码突然引起错误时,它是必须更改的平台。在这里,它甚至不是PHP真的改变,而是它使用的PRCE库。它被升级为8.37的PHP 5.6.9(http://php.net/ChangeLog-5.php)出于安全原因。现在,我们把所有的碎片到位了。

PHP 5.6.9更新了PRCE到8.34,导致正则表达式失败‘未找到之前检查的引用子模式’错误。过滤器拒绝地址有效,因为它失败了,并且邮件不是从WordPress发送的。

请注意,再次,严格的比较有助于区分错误和失败的过滤器。确实 :

<?php
var_dump(preg_match("this is not a valid regex", "123")); // return false and an error
var_dump(preg_match("/this is a valid regex/", "123") ; // return 0 (nothing found)
?>

另一方面,安全性明智,验证器返回很好‘false’如果正则表达式失败,因为地址或正则表达式本身。

有趣的是,一旦我理解这个问题,我发现就马上找到了具有同样问题的其他库:(Swiftmailer, PHPMailer. (sic), OwnCloudcore.)

像往常一样,这里最困难的是症状之间的距离(电子邮件不会出门)和实际修复(修复正则表达式)。我记得在日志中早早看这个PREG_MATCH错误,但匆匆丢弃它:年轻,愚蠢!

大学教师’t fix the framework

我希望这有助于每个人遇到同样的问题。注释对于未来:修复源中的代码将打破下一个升级,所以现在我必须小心它。希望它将在下一个WordPress升级中修复。

One thought on “WordPress不发送邮件,而PHP 5.6.9确实如此

  1. pingback: 主页

评论被关闭。