ホームページ >バックエンド開発 >PHPチュートリアル >win2003_PHP チュートリアルで preg_match_all を使用することによって引き起こされる Apache クラッシュの解決策
この記事では、win2003 で preg_match_all を使用すると Apache がクラッシュする問題の解決策を紹介します。このような問題に遭遇した友人は参考にしてください。
Apache/2.2.9 (Win32) + PHP/5.2.17、分析と一致比較に正規表現 preg_match_all (preg_match_all("/ni(.*?)wo/", $html, $matches); など) を使用文字列 $html が長い場合 (通常、収集された Web ページのソース コードを分析するために使用される 100,000 バイトを超える)、Apache サーバーはクラッシュし、自動的に再起動します。
Apache エラー ログに次のプロンプトがあります:
[Thu Apr 11 18:31:31 2013] [通知] 親: 子プロセスがステータス 128 で終了しました -- 再起動中です。
[Thu Apr 11 18:31:31 2013] [通知] Apache/2.2.9 (Win32) PHP/5.2.17 設定済み -- 通常の操作を再開します
[Thu Apr 11 2013 18:31:31] [お知らせ] サーバー構築: Jun 13 2008 04:04:59
[Thu Apr 11 18:31:31 2013] [お知らせ] 親: 子プロセス 2964 を作成しました
[Thu Apr 11 18:31:31 2013] [お知らせ] WinSock2 API AcceptEx() の使用禁止
[Thu Apr 11 18:31:31 2013] [通知] 子 2964: 子プロセスが実行中です
[Thu Apr 11 18:31:31 2013] [お知らせ] Child 2964: 開始ミューテックスを取得しました
[Thu Apr 11 18:31:31 2013] [通知] Child 2964: 350 ワーカー スレッドを開始します。
[Thu Apr 11 18:31:31 2013] [通知] Child 2964: ポート 80 でリッスンしています
Apache 公式およびフォーラムの情報を調べた結果、Win プラットフォームで通常の preg_match_all または preg_match を使用して比較的長い文字列を分析する場合、Apache のクラッシュと再起動の原因は、Windows プラットフォームでデフォルトで割り当てられたスレッド スタック スペース ThreadStackSize であることがわかりました。小さすぎます。 win32 のデフォルト値はわずか 256KB ですが、Linux のデフォルト値は 8M です。これが、同じプログラムが Linux プラットフォームでは正常に動作するのに、Win プラットフォームでは正常に動作しない理由です。
PCRE ライブラリの公式説明によると、256 KB のスタック領域に対応する pcre.recursion_limit サイズは 524 を超えてはなりません。
以下は、さまざまな実行可能スタック サイズに対する pcre.recursion_limit の安全な値の表です:
以下は、Stacksize と pcre.recursion_limit に対応する推奨安全値です。この値を超えると、スタック オーバーフローが発生する可能性が高く、Apache がクラッシュします。
64 MB 134217
32 MB 67108
16 MB 33554
8MB16777
4MB8388
2MB 4194
1MB2097
512KB 1048
256 KB 524
スタック サイズを調整していない場合は、正規表現を使用して PHP ページの先頭にスタック サイズを追加する必要があります:
代码如下 | 复制幣 | ||||
$resultsArray = preg_match_all("/table.*?/isU", $html, $contents); if ($resultsArray === 0){ echo get_pcre_err(); } 関数 get_pcre_err(){ $pcre_err = preg_last_error(); // PHP 5.2 以降。 if ($pcre_err === PREG_NO_ERROR) { $msg = '不一致に成功しました。'; } その他 { // preg_match エラー! スイッチ ($pcre_err) { ケース PREG_INTERNAL_ERROR: $msg = 'PREG_INTERNAL_ERROR'; 休憩; ケース PREG_BACKTRACK_LIMIT_ERROR: $msg = 'PREG_BACKTRACK_LIMIT_ERROR'; 休憩; ケース PREG_RECURSION_LIMIT_ERROR: $msg = 'PREG_RECURSION_LIMIT_ERROR'; 休憩; ケース PREG_BAD_UTF8_ERROR: $msg = 'PREG_BAD_UTF8_ERROR'; 休憩; ケース PREG_BAD_UTF8_OFFSET_ERROR: $msg = 'PREG_BAD_UTF8_OFFSET_ERROR'; 休憩; デフォルト: $msg = '認識できない PREG エラー'; 休憩; } } return($msg); } 通常の修飾子の説明は U:
ここで、32 ビット Apache プログラムは最大約 2GB のメモリ空間しか使用できないことに注意してください。 したがって、ThreadStackSize と ThreadsPerChild を乗算した値 (8M * 200) が 2G を超えてはなりません。2G を超えない場合、Apache を起動できず、表示されるエラー ログは次のとおりです。 声明: この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。 |