[Php] require_onceが使いにくいのはなぜですか?


Answers

このスレッドは、すでに "解決策が投稿されました"という理由で私を嫌にしています。それは、すべての目的と目的のために間違っています。 列挙しましょう:

  1. 定義はPHPで本当に高価です。 それたり自分でテストたりすることはできますが、PHPでグローバル定数を定義する唯一の効率的な方法は、拡張を介してです。 (クラスの定数は実際にはかなり賢明なパフォーマンスの賢明ですが、これは不都合な点です、2)

  2. require_once()適切に使用している場合、つまりクラスを含める場合は、定義する必要はありません。 class_exists('Classname')class_exists('Classname')かを確認してください。 インクルードするファイルにコードが含まれている場合(つまり手続き的な方法で使用している場合require_once()require_once()が必要になることは絶対にありません。 ファイルをインクルードするたびに、サブルーチン呼び出しを行うと仮定します。

ですから、しばらくの間、多くの人がその包含にclass_exists()メソッドを使用しました。 私はそれが醜いので好きではありませんが、 require_once()はいくつかの最新バージョンのPHPの前にはかなり非効率的でした。 しかし、これは修正されています。条件付きでコンパイルしなければならない余分なバイトコードと余分なメソッド呼び出しは、内部ハッシュテーブルのチェックをはるかに上回ります。

今、入場料:このことはテストするのが難しいです。実行時間が非常に少ないためです。

インタプリタがヒットするたびに解析モードに戻り、オペコードを生成してから戻る必要があるため、原則としてPHPではコストがかかるので、これを考慮する必要があります。 100以上のインクルードをお持ちの場合、これは間違いなくパフォーマンスに影響を与えます。 require_onceを使用するか使用しないかが重要な問題である理由は、オペコード・キャッシュの寿命を延ばすためです。 これに関する説明はここにありますが、これは次のようなものです。

  • 解析時間中に要求の全ライフサイクルにわたって必要なインクルードファイルが何であるかを正確に知っていれば、最初のものをrequire()すれば、opcodeキャッシュが他のものをすべて処理します。

  • オペコードキャッシュを実行していない場合、あなたは難しい場所にいます。 すべてのインクルードを1つのファイルにインライン展開することは、開発中にのみ行います(実稼働環境でのみ行います)が時間を解析するのには確かに役立ちますが、それは苦労します。要求。

  • オートロードは非常に便利ですが、インクルードが完了するたびにオートロードロジックを実行する必要があるため、遅いです。 実際には、1つのリクエストに対して複数の特殊なファイルを自動ロードするだけでは問題は発生しませんが、必要なすべてのファイルを自動ロードするべきではありません。

  • おそらく10個のインクルードがある場合(これはエンベロープ計算の背後にあります)、このすべての問題は価値がありません。データベースのクエリなどを最適化するだけです。

Question

より良いPHPコーディング実践について読んだことは、速度のためにrequire_once使わないということを続けています。

どうしてこれなの?

require_onceと同じことを行うための適切な方法は何ですか? それが問題なら、私はPHP5を使用しています。




あなたはそれを避けるために言うこれらのコーディング慣行へのリンクを私達に与えることができますか? 限り、私は懸念している、 それは完全な非問題です。 私は自分自身でソースコードを見ていませんが、 includeinclude_once唯一の違いは、 include_onceがそのファイル名を配列に追加し、その都度配列をチェックするということです。 その配列をソートしたままにするのは簡単でしょうから、それを検索するのはO(log n)でなければならず、中規模のアプリケーションでさえ数十含まれています。




私はPEARのドキュメントでrequire、require_once、include、include_onceの推奨があると思います。 私はそのガイドラインに従っています。 あなたのアプリケーションはより明確になります。




*_once()関数はすべての親ディレクトリをstatして、あなたがインクルードしているファイルが既にインクルードされているものと同じでないことを確認します。 これは減速の理由の一部です。

ベンチマークのためにSiegeようなツールを使うことをお勧めします。 提案されたすべての方法論を試し、応答時間を比較することができます。

Tech Your Universeの require_once()詳細




私の個人的な意見はrequire_once(またはinclude_once)の使用法は悪い習慣です。あなたがすでにそのファイルをインクルードしている場合はrequire_onceがチェックし、重複したファイルのエラーは抑制します(関数/クラス/などの重複宣言のような) 。

ファイルを含める必要があるかどうかを知っておく必要があります。




それは悪い機能を使用していません。 全体的なコードベースで、いつどのように使用するのかを間違って理解しています。 私はちょっとだけ、誤解を招くような文脈を追加します:

人々はrequire_onceが遅い関数であると考えるべきではありません。 あなたはあなたのコードを一方的にまたは別の方法で含める必要があります。 require_once()require()の速度は問題ではありません。 それは、それを盲目的に使用する結果となる可能性のある警告の実行を妨げる性能についてです。 コンテキストを考慮せずに広く使用すると、膨大なメモリの浪費や無駄なコードが発生する可能性があります。

私が本当に悪いと思っていたのは、巨大なモノリシックなフレームワークが、特に複雑なオブジェクト指向の環境で、すべての間違った方法でrequire_once()を使うときです。

多くのライブラリで見られるように、すべてのクラスの先頭にrequire_once()を使用する例を考えてみましょう:

require_once("includes/usergroups.php");
require_once("includes/permissions.php");
require_once("includes/revisions.php");
class User{
  //user functions
}

したがって、 Userクラスは他の3つのクラスをすべて使用するように設計されています。 けっこうだ! しかし、訪問者がサイトをブラウズしていてログインしていなくても、フレームワークがロードされた場合はどうなりますか? require_once("includes/user.php"); 1回のリクエストごとに

それは、その特定の要求の間に使用されない1 + 3の不要なクラスを含みます。 これは、肥大化したフレームワークが、5MB以下ではなく、要求ごとに40MBを使用することになります。

それが誤用される可能性がある他の方法は、クラスが他の多くのものによって再利用されるときです! helper関数を使用する約50のクラスがあるとします。 helpersがロードされているときにhelpersを利用できるようにするには、次のようにします。

require_once("includes/helpers.php");
class MyClass{
  //Helper::functions();//etc..
}

ここには何も問題はありません。 しかし、1ページのリクエストに15の類似クラスが含まれているとします。 あなたはrequire_once 15回実行しています。

require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");

require_once()を使用すると、不要な行を解析する必要がなく、技術的に14回その関数を実行する際のパフォーマンスに影響を与えます。 同じような問題を抱えている他のクラス10人ほどで、それほど無意味な繰り返しコードの100行以上を占める可能性があります。

それで、おそらくrequire("includes/helpers.php");を使う価値がrequire("includes/helpers.php"); あなたのアプリやフレームワークのブートストラップで、代わりに。 しかし、すべてが相対的であるためhelpersクラスの重みと使用頻度がrequire_once() 15〜100行を節約する価値があるどうかによって異なります。 しかし、任意の要求に対してhelpersファイルを使用しない確率がnoneの場合、 requireは確実にメインクラスにあるはずです。 各クラスにrequire_onceを別々に持つことは、リソースの無駄になります。

require_once関数は必要なときに便利ですが、すべてのクラスをロードするためにどこでも使えるモノリシックなソリューションとはみなされません。




はい、それは普通のol 'require()よりも若干高価です。 私は、あなたがコードをいくつかのサイクルを節約するので、* _once()関数を使わないでください。

しかし、_once()関数を使用することはあなたのアプリを終了させません。 基本的には、 あなたのインクルードを整理する必要がないという口実として使ってはいけません 。 場合によっては、それを使用することはやむを得ないことであり、大きな問題ではありません。