这个PHP代码会让Apache崩溃吗


Does this PHP code crash Apache for anyone else?

preg_match_all('/(a)*/', str_repeat('a', 1000), $matches);

(编辑:稍微更改regexp,使其更简单,同时仍然崩溃(

我在PHP 5.3.5和Apache 2.0上运行了它,它导致服务器崩溃。如果我将339更改为338,它就不会崩溃,所以对我来说这似乎是一个错误http://bugs.php.net/但它已经倒下了。这是一个PHP错误吗?它会为其他人崩溃吗?

编辑:将代码更改为

preg_match_all('/(?:a)*/', str_repeat('a', 339), $matches);

允许在崩溃之前使用更长的字符串。如果它没有崩溃,请尝试将字符串长度增加10或100倍,因为这可能是内存问题,您可能有更多内存。

编辑2:崩溃是一个完整的进程崩溃,在Windows 7上,我在执行后立即收到"结束任务"消息。

编辑3:如果崩溃是由于过多的回溯造成的,并且上面的例子显然会导致崩溃,那么以下不应该:

preg_match('/[^"'']*(;|$)/',
               str_repeat('x', 1000), $matches);

这是我真正崩溃的代码。它只是通过;拆分多个SQL查询,同时允许;位于单引号或双引号内。为什么这会引起如此多的回溯,我该如何解决?

问题不在于内存或执行时间。。。

ini_set('pcre.backtrack_limit', 10000);

如有必要,可以10000降低到不同的值。有关详细信息,请参阅http://php.net/manual/en/pcre.configuration.php.

如果你想测试它崩溃的地方:

<?php
ini_set('pcre.backtrack_limit', 10000);
for ( $i = 1; $i < 65535; $i++ )
{
  echo $i . PHP_EOL;
  preg_match_all('/(a)*/', str_repeat('a', $i), $matches);
}
?>