PHPのset_error_handler関数の使用

Jul 29, 2016 am 09:00 AM
error handler

プログラムを作成するときは、必ず問題が発生します (頻繁に問題に遭遇します)。PHP でエラーが発生すると、エラー スクリプトの場所、行番号、および理由が表示されます。大したことではないと言う人も多い。実際、デバッグ段階では、これは実際には問題ではなく、エラー パスを示すことが必要だと思います。

しかし、一部の侵入者にとって、実際のパスが漏洩した場合の影響は想像を絶するものであり、実際、多くのサーバーがこの問題を抱えています。ネットワーク管理者の中には、PHP 設定ファイルの display_errors を Off に設定するだけで問題を解決する人もいます (私たちがそうしたようです) が、この方法はあまりにも消極的すぎると思います。

デバッグのためにエラー情報を返すために PHP が本当に必要になる場合があります。また、何か問題が発生した場合は、ユーザーに説明したり、別のページに移動したりする必要がある場合もあります。

それで、解決策は何でしょうか?

set_error_handler()
ログイン後にコピー

PHP は 4.1.0 以降、カスタム エラー処理ハンドラー用の関数 set_error_handler() を提供していますが、それを知っているスクリプト作成者はほとんどいません。 set_error_handler 関数はエラー パスの漏洩を防ぐことができますが、もちろん他の関数もあります。

  1. はエラーをブロックするために使用できます。 エラーが発生すると、一部の情報がユーザーに公開され、ハッカーが Web サイトを攻撃するツールとなる可能性が非常に高くなります。 次に、ユーザーにあなたのレベルが非常に低いと感じさせます。
  2. エラー情報を書き留めて、本番環境の問題を時間内に発見することができます。
  3. エラーが発生した場合は、事前に定義されたエラー ページへのジャンプを表示して、ユーザー エクスペリエンスを向上させることができます。
  4. 実稼働環境で何かをデバッグする必要がある場合に、それを使用しているユーザーに影響を与えたくない場合があります。
  5. 。 。 。 。

set_error_handler の使用法は次のとおりです:

<span>string</span> set_error_handler ( callback error_handler [, <span>int</span> error_types])
ログイン後にコピー

ここで、カスタム エラー処理を使用して実際のパスをフィルタリングします。変数 $admin があるとします。これを使用して、訪問者が管理者であるかどうかを判断します (この判断は IP またはログイン ユーザー ID によって行うことができます)

<span>//</span><span>admin为管理员的身份判定,true为管理员。 
</span><span>//</span><span>自定义的错误处理函数一定要有这4个输入变量$errno,$errstr,$errfile,$errline,否则无效。</span><span>function my_error_handler($errno,$errstr,$errfile,$errline) 
{ 
     </span><span>//</span><span>如果不是管理员就过滤实际路径 </span><span>if</span>(!<span>admin) 
    { 
        $errfile</span>=str_replace(getcwd(),<span>""</span><span>,$errfile); 
        $errstr</span>=str_replace(getcwd(),<span>""</span><span>,$errstr); 
    } 
     </span><span>switch</span><span>($errno) 
    { 
        </span><span>case</span><span> E_ERROR: 
          echo </span><span>"</span><span>ERROR: [ID $errno] $errstr (Line: $errline of $errfile) \n</span><span>"</span><span>; 
        echo </span><span>"</span><span>程序已经停止运行,请联系管理员。</span><span>"</span><span>; 
        </span><span>//</span><span>遇到Error级错误时退出脚本 </span><span>break</span><span>; 
        </span><span>case</span><span> E_WARNING: 
        echo </span><span>"</span><span>WARNING: [ID $errno] $errstr (Line: $errline of $errfile) \n</span><span>"</span><span>; 
        </span><span>break</span><span>; 
        </span><span>default</span><span>: 
        </span><span>//</span><span>不显示Notice级的错误 </span><span>break</span><span>; 
        } 
}  </span>
ログイン後にコピー

このようにして、エラー処理関数がカスタマイズされているため、このカスタム関数にエラー処理を引き渡すのはどうでしょうか?

<span>//</span><span> 应用到类 </span>set_error_handler(array(&$<span>this</span>,<span>"</span><span>appError</span><span>"</span><span>)); 
</span><span>//</span><span>示例的做法 </span>set_error_handler(<span>"</span><span>my_error_handler</span><span>"</span>);  
ログイン後にコピー

とても簡単です。このようにして、セキュリティとデバッグの利便性の間の矛盾をうまく解決できます。また、Web サイトのスタイルに合わせてエラー メッセージをより美しくすることも考えられます。

元の作成者は、注意が必要な 2 つの点を指摘しました。同胞の注意を引くことを願って、ここに投稿します:

  1. E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING は、このハンドルでは処理されません。つまり、最もオリジナルな方法で表示されます。ただし、これらのエラーはコンパイル エラーまたは PHP カーネル エラーによって発生するものであり、通常の状況では発生しません。
  2. set_error_handler()使用後はerror_reporting()が無効になります。つまり、すべてのエラー (上記のエラーを除く) は、処理のためにカスタム関数に渡されます。

<span>//</span><span>先定义一个函数,也可以定义在其他的文件中,再用require()调用  </span><span>function myErrorHandler($errno, $errstr, $errfile, $errline)  
{  
     </span><span>//</span><span>为了安全起见,不暴露出真实物理路径,下面两行过滤实际路径  </span>    $errfile=str_replace(getcwd(),<span>""</span><span>,$errfile);  
    $errstr</span>=str_replace(getcwd(),<span>""</span><span>,$errstr);  
  
    </span><span>switch</span><span> ($errno) {  
    </span><span>case</span><span> E_USER_ERROR:  
  
     echo </span><span>"</span><span><b>My ERROR</b> [$errno] $errstr<br />\n</span><span>"</span><span>;  
        echo </span><span>"</span><span>  Fatal error on line $errline in file $errfile</span><span>"</span><span>;  
        echo </span><span>"</span><span>, PHP </span><span>"</span> . PHP_VERSION . <span>"</span><span> (</span><span>"</span> . PHP_OS . <span>"</span><span>)<br />\n</span><span>"</span><span>;  
        echo </span><span>"</span><span>Aborting...<br />\n</span><span>"</span><span>;  
        exit(</span><span>1</span><span>);  
        </span><span>break</span><span>;  
  
    </span><span>case</span><span> E_USER_WARNING:  
        echo </span><span>"</span><span><b>My WARNING</b> [$errno] $errstr<br />\n</span><span>"</span><span>;  
        </span><span>break</span><span>;  
  
    </span><span>case</span><span> E_USER_NOTICE:  
        echo </span><span>"</span><span><b>My NOTICE</b> [$errno] $errstr<br />\n</span><span>"</span><span>;  
        </span><span>break</span><span>;  
  
    </span><span>default</span><span>:  
        echo </span><span>"</span><span>Unknown error type: [$errno] $errstr<br />\n</span><span>"</span><span>;  
        </span><span>break</span><span>;  
    }  
  
    </span><span>/*</span><span> Don't execute PHP internal error handler </span><span>*/</span><span>return</span><span>true</span><span>;  
}  
  
</span><span>//</span><span>下面开始连接MYSQL服务器,我们故意指定MYSQL端口为3333,实际为3306。  </span>$link_id=@mysql_pconnect(<span>"</span><span>localhost:3333</span><span>"</span>,<span>"</span><span>root</span><span>"</span>,<span>"</span><span>password</span><span>"</span><span>);  
set_error_handler(myErrorHandler);  
</span><span>if</span> (!<span>$link_id) {  
    trigger_error(</span><span>"</span><span>出错了</span><span>"</span><span>, E_USER_ERROR);  
}  </span>
ログイン後にコピー

さて、要約すると、set_error_handler の 3 つの使用法は次のとおりです。

<span>class</span><span> CallbackClass {  
   function CallbackFunction() {  
       </span><span>//</span><span> refers to $this  </span><span>   }  
  
   function StaticFunction() {  
       </span><span>//</span><span> doesn't refer to $this  </span><span>   }  
}  
  
function NonClassFunction($errno, $errstr, $errfile, $errline) {  
}  
  
</span><span>//</span><span> 三种方法如下:  </span><span>1</span>: set_error_handler(<span>'</span><span>NonClassFunction</span><span>'</span>);  <span>//</span><span> 直接转到一个普通的函数 NonClassFunction  </span><span>2</span>: set_error_handler(array(<span>'</span><span>CallbackClass</span><span>'</span>, <span>'</span><span>StaticFunction</span><span>'</span>)); <span>//</span><span> 转到 CallbackClass 类下的静方法 StaticFunction  </span><span>3</span>: $o =& <span>new</span><span> CallbackClass();  
    set_error_handler(array($o, </span><span>'</span><span>CallbackFunction</span><span>'</span>));  <span>//</span><span> 转到类的构造函数,其实本质上跟下面的第四条一样。  </span><span>4</span>. $o = <span>new</span><span> CallbackClass();  
  
  
</span><span>//</span><span> The following may also prove useful:  </span><span>class</span><span> CallbackClass {  
   function CallbackClass() {  
       set_error_handler(array(</span>&$<span>this</span>, <span>'</span><span>CallbackFunction</span><span>'</span>)); <span>//</span><span> the & is important  </span><span>   }  
     
   function CallbackFunction() {  
       </span><span>//</span><span> refers to $this  </span><span>   }  
}  </span>
ログイン後にコピー

上記では、PHP の set_error_handler 関数の使用方法を、関連する側面も含めて紹介しています。PHP チュートリアルに興味のある友人に役立つことを願っています。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHP 致命的エラーの解決策: 未定義メソッド PDO::prepare() の呼び出し PHP 致命的エラーの解決策: 未定義メソッド PDO::prepare() の呼び出し Jun 22, 2023 pm 06:40 PM

PHP は、長い間使用されている人気のある Web 開発言語です。 PHP に統合された PDO (PHP Data Object) クラスは、Web アプリケーションの開発中にデータベースと対話する一般的な方法です。ただし、一部の PHP 開発者がよく遭遇する問題は、PDO クラスを使用してデータベースと対話するときに、次のようなエラーが表示されることです。

Vue アプリケーションで axios を使用しているときに「Uncaught (in Promise) Error: Request failed with status code 500」が発生した場合はどうすればよいですか? Vue アプリケーションで axios を使用しているときに「Uncaught (in Promise) Error: Request failed with status code 500」が発生した場合はどうすればよいですか? Jun 24, 2023 pm 05:33 PM

Vue アプリケーションで axios を使用するのは非常に一般的です。axios は、ブラウザーと Node.js で使用できる Promise ベースの HTTP クライアントです。開発プロセス中に、「Uncaught(inpromise)Error: Requestfailedwithstatuscode500」というエラー メッセージが表示されることがありますが、開発者にとって、このエラー メッセージは理解および解決が難しい場合があります。この記事ではこれについて説明します

C++ コードの「エラー: 'datatype' の前に初期化子が必要です」問題を解決する C++ コードの「エラー: 'datatype' の前に初期化子が必要です」問題を解決する Aug 25, 2023 pm 01:24 PM

C++ コードの「error:expectedinitializerbefore'datatype'」問題を解決します。C++ プログラミングでは、コードを作成するときにコンパイル エラーが発生することがあります。一般的なエラーの 1 つは、「error:expectedinitializerbefore'datatype'」です。このエラーは通常、変数宣言または関数定義で発生し、プログラムが正しくコンパイルされなかったり、

C++ コードの「エラー: 不完全な型は許可されません」の問題を解決する C++ コードの「エラー: 不完全な型は許可されません」の問題を解決する Aug 26, 2023 pm 08:54 PM

C++ コードの「error:incompletetypeisnotallowed」問題を解決します。C++ プログラミング プロセス中に、コンパイル エラーが発生することがあります。一般的なエラーの 1 つは、「error:incompletetypeisnotallowed」です。このエラーは通常、不完全な型を操作することによって発生します。この記事では、このエラーの原因を説明し、いくつかの解決策を提供します。まず、私は

0271: リアルタイムクロックエラーによりコンピュータの電源が入らない場合はどうすればよいですか? 0271: リアルタイムクロックエラーによりコンピュータの電源が入らない場合はどうすればよいですか? Mar 13, 2023 am 11:30 AM

起動できない「0271: リアルタイム クロック エラー」の解決策: 1. F1 キーを押し、表示されるインターフェイスでオプション バーを 3 番目の項目「日付/時刻」に移動します; 2. システム時刻を手動で現在の時刻に変更します。 1 回; 3. F10 キーを押し、ポップアップ ダイアログ ボックスで [はい] を選択します; 4. ノートブックを再度開いて、通常どおり起動します。

PHP 致命的エラーの解決策: 未定義関数 mysqli_connect() の呼び出し PHP 致命的エラーの解決策: 未定義関数 mysqli_connect() の呼び出し Jun 23, 2023 am 09:40 AM

PHP を使用して Web アプリケーションを作成する場合、データの保存に MySQL データベースがよく使用されます。 PHP は、MySQLi と呼ばれる MySQL データベースと対話する方法を提供します。ただし、MySQLi を使用している場合、以下に示すようなエラー メッセージが表示されることがあります。 PPHPFatalerror:Calltounknownfunctionmysqli_connect() このエラー メッセージは、PHP が MySQLi を見つけられないことを意味します。

PHP 警告の解決方法: fopen(): ストリームを開けませんでした: そのようなファイルまたはディレクトリはありません PHP 警告の解決方法: fopen(): ストリームを開けませんでした: そのようなファイルまたはディレクトリはありません Aug 19, 2023 am 10:44 AM

PHPWarning:fopen():failedtoopenstream:No suchfileordirectory PHP 開発を使用する過程で、ファイル操作の問題がよく発生します。その 1 つが「PHPWarning:fopen():failedtoopenstream:No suchfileordirectory」です。

PHP 致命的エラーの解決策: メンバー関数 fetch() の呼び出し PHP 致命的エラーの解決策: メンバー関数 fetch() の呼び出し Jun 23, 2023 am 09:36 AM

Web アプリケーション開発に PHP を使用する場合、多くの場合データベースを使用する必要があります。データベースを使用すると、エラー メッセージがよく発生します。その中でも、PHPFatalerror: Calltoamemberfunctionfetch() は、PDO を使用してデータベースをクエリするときに発生する比較的一般的なエラーです。では、このエラーの原因と解決方法は何でしょうか?この記事ではそれについて詳しく説明します。 1. エラーの原因

See all articles