当前位置:  操作系统/服务器>linux

win2003下PHP使用preg_match_all导致apache崩溃问题的解决方法

    来源: 互联网  发布时间:2014-08-25

    本文导语:  小编的平台是windows server 2003(32位系统) + Apache/2.2.9 (Win32) + PHP/5.2.17,在使用正则表达式 preg_match_all (如 preg_match_all("/ni(.*?)wo/", $html, $matches);)进行分析匹配比较长的字符串 $html 时(大于10万字节,一般用于分析采集回来的网...

小编的平台是windows server 2003(32位系统) + Apache/2.2.9 (Win32) + PHP/5.2.17,在使用正则表达式 preg_match_all (如 preg_match_all("/ni(.*?)wo/", $html, $matches);)进行分析匹配比较长的字符串 $html 时(大于10万字节,一般用于分析采集回来的网页源码),Apache服务器会崩溃自动重启。
    在Apache错误日志里有这样的提示:

代码如下:
[Thu Apr 11 18:31:31 2013] [notice] Parent: child process exited with status 128 -- Restarting.
[Thu Apr 11 18:31:31 2013] [notice] Apache/2.2.9 (Win32) PHP/5.2.17 configured -- resuming normal operations
[Thu Apr 11 18:31:31 2013] [notice] Server built: Jun 13 2008 04:04:59
[Thu Apr 11 18:31:31 2013] [notice] Parent: Created child process 2964
[Thu Apr 11 18:31:31 2013] [notice] Disabled use of AcceptEx() WinSock2 API
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Child process is running
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Acquired the start mutex.
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Starting 350 worker threads.
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Listening on port 80.

    经过查阅Apache官方以及论坛资料后,发现win平台下用正则 preg_match_all 或preg_match 分析比较长的字符串时,导致apache崩溃重启的原因是windows平台下默认分配的线程堆栈空间 ThreadStackSize 太小导致的。 win32默认只有256KB,而在 linux下默认值是 8M,这就是为什么同样的程序在 linux平台下正常,而在 win平台下不正常的原因。
    根据PCRE library的官方说明:256 KB 的堆栈空间对应的pcre.recursion_limit大小应该不超过524。
Here is a table of safe values of pcre.recursion_limit for a variety of executable stack sizes:
下面就是一张Stacksize和pcre.recursion_limit对应的建议安全值,超过这个数值就极有可能发生堆栈溢出,apache crash:
代码如下:
Stacksize   pcre.recursion_limit
 64 MB      134217
 32 MB      67108
 16 MB      33554
  8 MB      16777
  4 MB      8388
  2 MB      4194
  1 MB      2097
512 KB      1048
256 KB      524

如果你没有调整堆栈大小,就必须在使用正则的PHP页面最开头加入:

代码如下:

查看具体的错误可以使用下面的代码:

代码如下:
$resultsArray = preg_match_all("/table.*?/isU", $html, $contents);
if ($resultsArray === 0){
echo get_pcre_err();
}
function get_pcre_err(){
        $pcre_err = preg_last_error();  // PHP 5.2 and above.
        if ($pcre_err === PREG_NO_ERROR) {
            $msg = 'Successful non-match.';
        } else {
            // preg_match error!
            switch ($pcre_err) {
                case PREG_INTERNAL_ERROR:
                    $msg = 'PREG_INTERNAL_ERROR';
                    break;
                case PREG_BACKTRACK_LIMIT_ERROR:
                    $msg = 'PREG_BACKTRACK_LIMIT_ERROR';
                    break;
                case PREG_RECURSION_LIMIT_ERROR:
                    $msg = 'PREG_RECURSION_LIMIT_ERROR';
                    break;
                case PREG_BAD_UTF8_ERROR:
                    $msg = 'PREG_BAD_UTF8_ERROR';
                    break;
                case PREG_BAD_UTF8_OFFSET_ERROR:
                    $msg = 'PREG_BAD_UTF8_OFFSET_ERROR';
                    break;
                default:
                    $msg = 'Unrecognized PREG error';
                    break;
            }
        }
    return($msg);
}

对于正则的修饰符 isU 说明:

代码如下:
i: 表示in-casesensitive,即大小写不敏感
s: PCRE_DOTALL,表示点号可以匹配换行符。
U: 表示PCRE_UNGREEDY,表示非贪婪,相当于perl/python语言的.*?,在匹配过程中,对于.*正则,一有匹配立即执行,而不是等.*搜索了所有字符再一一返回

    在使用正则表达式时,我们应该尽量避免递归调用,递归容易导致堆栈溢出。比如:
/


    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 安装Linux 9.0后,导致Win98下无法打开资源管理器的问题。
  • 安装了RH8.0,结果导致WIn2000启动巨慢,如何解决?(100)
  • Win98重新安装,导致Linux无法?
  • 安装Linux7.3后,在Win2K中删掉Linux分区,导致无法正常启动(显示grub>;),且无法从光盘启动,该如何解决?请帮忙
  • win7, win8安装docker需要了解的概念
  • 我系统安装了win2000,win98,linux,现在登录时只能进入win98和linux,无法进入win2000
  • win7,win8安装Docker具体过程
  • 有那位在win2000和win98上都装过tomcat,为什么我在win2000可以很容易装上,在win98就装不上,有什么区别?
  • win7,win8安装docker的依赖条件
  • 我在双系统win98@win2000下重装win98应该备份哪几个文件?
  • win7/Windows7系统下载地址搜集整理
  • win2000+jbuilder6+oracle817编出的程序,在win2000下执行很好,在win98下却访问不了oracle数据库
  • 怎样重装win7系统?win7重装系统步骤详细图文介绍
  • 先装win me 再装redhat 9.0 再在win me 下装win xp ,linux 不见了.怎么恢复linux啊?
  • Win7 64位下mysql 下载、安装与配置图文教程
  • 如何让win2000和linux共存。我装好WIN2000,再装LINUX7.0,但LILO只能找到LINUX,不能引导WIN2000
  • 安装运行微软win7/Windows7系统要求及官方下载地址
  • 要安装win98、win2000服务器、win2003服务器、LINUX系统,请问该按什么顺序安装?
  • 如何在win7,win8下面启动docker
  • 我想知道LINUX如何与WIN98,WIN2000共享资源?
  • 在已有的win98+win200server下安装linux
  • 高分请教!!关于win98,win2000,sco unix 的安装问题
  • 在已经装有win98和win2000的机器上怎样装UNIX系统?
  • 为什么装上win98、2000、linux后,我运行win2000时的速度非常慢???
  • win98,win2000,linux,FreeBSD能共存吗?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3