グループの友人が 2 か月前に質問しました。彼はこう言いました。「今、彼らの会社のプロジェクトには、オンラインでのパフォーマンスが非常に悪いモジュールがあります。問題が長い間見つからず、上司が激怒していました。尋ねてください。」彼には、すべてのクラス メソッドの実行時間を記録して分析するよう求められましたが、それが現在のプロジェクトのパフォーマンスに影響を与えることはありません。「上司は、パフォーマンスに影響を与える特定の箇所を分析するためにこの情報を記録し、プロジェクトの実行後に削除するように彼に依頼しました。」一定期間。この要件により、2 つの問題が生じます。1 つ目は、このモジュール内のすべてのクラス メソッドの実行時間を監視する方法です (パフォーマンス自体は非常に悪いですが)。分析する 2 つの質問:
1. このモジュール内のすべてのクラス メソッドの実行時間を監視する方法
この問題に対して彼が最初に考えたのは、すべてのクラス メソッドが実行されるまでの時間を記録するコードを追加することでした。データを返す前に計算と実行を実行し、ログに記録します。この方法は実行可能である必要があり、パフォーマンスに大きな影響を与えることはありませんが、プログラマは怠け者です。このような実装を行っても、私たちはプログラマではありません。これを削除すると、変更するコードの量が多すぎて、意味のない技術的な作業が長時間繰り返されることになります。次に、これを再度削除するとクラッシュします。もちろん、私の友人は誰もそんなことをしなかったので、私はこの奇妙なニーズについて学びました。
このようなタスクを解決するのは非常に困難です。php5.3 より前では、静的メソッドを 1 つずつ追加することしかできませんでした。 php5.3 の新しい __callStatic() マジック メソッド。これら 2 つのマジック メソッドはクラス メソッドが存在しない場合にのみ役立つのではないかと疑問に思う人もいるかもしれません。どうすればこの要件を達成できるのでしょうか。この質問のコードは後で見ていきます。以下の 2 番目の質問を分析してみましょう。
第二に、現在のプロジェクトのパフォーマンスに影響を与えずにプロジェクトを完了するにはどうすればよいでしょうか?
なぜこの問題があると言えるのでしょうか?以前に要件を分析したときに確かに存在していましたが、最初の質問に回答したときに解決策がすでに述べられていたため、__call() と __callStatic() を使用してクラス メソッドをオーバーロードするのは実装が比較的簡単で、既存のメソッドにも適していると思います。プロジェクトのパフォーマンスへの影響は最小限です。
この質問では主に他のいくつかの方法について説明します。実際、xdebug、xhprof など、パフォーマンス分析を実現するための拡張機能が多数あります。xdebug はパフォーマンスの低下が大きく、アプリケーションでの使用には適していないことが知られています。 xhprof はパフォーマンスの低下が比較的小さいですが、正式な環境で使用されます。では、なぜ xhprof を使用しないのでしょうか?ポイントは 3 つあります: 1. パフォーマンスの低下が若干大きくなります。 2. ログ記録形式が柔軟性に欠けるため、ログ分析に問題が発生します。 3. 一部の関数はカウントできず、重大なエラーが発生します (call_user_func_array など)。解決策が決まったので、まずデモを見てみましょう
/** * 类方法性能监听 * * @author 戚银 thinkercode@sina.com * @date 2015-05-31 22:09 */class demo { /** * 普通类方法 * * @access public * @return void */ public function test1(){ for($i=0; $i<100; ++$i){ } } /** * 静态方法 * * @access public * @return void */ public static function test2(){ for($i=0; $i<100; ++$i){ } }}
上記のデモ クラスを見てください。これには、通常のメソッドと静的メソッドの 2 つのメソッドがあり、ビジネス層がそれを呼び出す方法です。
<?php(new demo())->test1();demo::test2();
原則として、クラスの外部のコードは変更せず、実装するためにクラスのみを調整することを保証します。以下では、__call() と __callStatic() を使用してクラス メソッドをオーバーロードします。 。はい、そうです。 、呼び出されたメソッドが存在しないようにし、クラス自体を変更するだけするには、メソッド名の前にアンダースコアを追加するだけです (このルールは自分で決定します)。そして、これら 2 つのメソッドを呼び出すと、 2 つのメソッドが出力されます。
この実装ではまだ多くのコード変更が必要ですが、これは非常に面倒です...実際、手元にあるツールを使用して実装するのは簡単です。これら 2 つのメソッドを基本クラスに記述し、すべてのクラスがこの基本クラスを継承するのは良い方法です。コンストラクターとデストラクターを除くクラス メソッド名の置換については、エディターを使用して直接バッチで置換でき、後で元に戻すこともできます。
注: 継承を使用して実装された場合、__callStatic() メソッドの __CLASS__ を調整する必要があります。
ここでは、ビジネス層がクラス メソッドを見つけられないように、クラス メソッドの前にアンダースコアを追加することで実装されています。実際、この例はメソッドの可視性を調整することによっても実装できますが、可視性の実装方法には次のような欠点があります。
1. 調整後 調整を元に戻したい場合、クラスメソッドの表示を間違えたり、どのメソッドが調整されたのか分かりません。2. 可視性の調整は、クラスのパブリック メソッドに対してのみ有効であり、プロテクト メソッドやプライベート メソッドには有効ではありません
もちろん、クラスのパブリック メソッドのパフォーマンスのみを記録する場合は、メソッドの可視性の変更を使用できますが、注意する必要があります。このメソッドが変更されたことを示すマークを追加します。クラスがこのクラスを継承すると、このメソッドにアクセスできなくなるため、パブリックからプライベートに変更する必要があります。