PHPモジュールエンジンの開発

ほぼすべてを含む、単純なものから非常に重くてかさばるものまで、さまざまなPHPエンジンがあります。

しかし、私の意見では、最高のエンジンは拡張可能です。 そして、それはその能力のヒープにもう少し結びつけることを提供するものではなく、その能力のいずれも存在しないが、選択できるもののみが存在するものです。

半年前、私はそのようなエンジンをどのように作成するのか疑問に思いました。 最初に書くことはブートローダーでした。 他のモジュールをロードする一種の疑似モジュール(後で詳しく説明します)。

構造を決定しましょう:モジュールが保存されているmodフォルダーがあるとしましょう。
たとえば、 / mod / staticpages / * 。 ローダー標準に従って、モジュールは構成ファイル、モジュールのメインクラス、およびオプションで接続されたライブラリで構成する必要があります。

繰り返しますが、たとえば、 staticpagesモジュール(静的ページの処理を担当)があり、 manifest.ini ファイルstaticpages.phpファイルで構成されます
1つ目はモジュール構成で、2つ目はメインモジュールクラスのファイルです。
まず、構成ファイルに次の構造を持たせます。
[Custom] name = "Static Pages"; author = "ShadowPrince"; devname = "staticpages"; version = "0.1"; 

このモジュールを処理すると、そのマニフェストが開き(この用語をさらに使用します)、必要なデータがモジュールから取得され、必要な操作が実行されます。

マニフェストに別のセクションを追加します。
 [Module] mainclass = "staticpages.php"; mainclassname = "StaticPages"; 

これで、このモジュールを処理するときに、クラスを含むファイルをロード(またはインクルード)して、そのインスタンスを作成できます。
これで、アルゴリズムは次のようになります。
1.すべてのフォルダー/ mod /を読み取ります。
2. manifest.iniがある場合、続行します。
3. mainclass値を取得し、このファイルを含めます。
4. devnameという名前のクラスのインスタンスを作成します。 これがまさにこのフィールドの目的です。
その結果、 $ staticpagesという名前のStaticPagesクラスのオブジェクトを取得します。 オブジェクトは他のモジュールとの便利な相互作用のためにグローバルになります。
これからのコードでは、このモジュールの機能を簡単かつ迅速に使用できます。

しかし、ここでもう1つの問題が発生します。
次のようなリクエストがあるとします: " ?Ins = staticpage&page = info "。これは、理論的にはinfoという静的ページを表示するはずです。 しかし、 Static Pagesモジュールはどのようにしてこれについて学習しますか?
もちろん、 ins = staticpageなど、クラスのコンストラクターにハンドラーを配置することもできますが、その時点では、 静的ページが機能するために必要な他のモジュールがロードされたかどうかはわかりませんが、一般的には価値がありますか?

そのため、マニフェストに別のセクションを追加する必要があります。
 [Run] run = "template()" 

すべてのモジュールをロードした後、2番目のステージである起動メソッドを起動します。
このセクションのrunパラメーターは、この段階で実行するクラスメソッドを指定します。 さて、この時点ですべてのモジュールは既にロードされており、簡単に相互にやり取りできます。

もう1つの状況-このセクションのpexモジュール(アクセス権を担当する)が現在のユーザーのアクセス権の読み込みを開始しているとしましょう。ただし、デフォルトで静的ページの表示を制限する必要があり、サードパーティのモジュールのコードに干渉することは好ましくありません。

マニフェスト内のパラメーターだけでなく、別の概念、つまりqueueとrequireを導入する必要があります。
この場合のキューは、何らかのアクションを実行するためのモジュールのキューです(これは明らかです)。
そして今- 静的ページモジュールの[実行]セクションを変更します。
 [Run] run = "template()" require = "pex" 

Static Pagesモジュールのtemplate()メソッドを実行しようとすると、ローダーはまずpexモジュールに対して同様のアクションを実行し、モジュールをキュー内でさらに移動し、残りのモジュールに対して同じ作業を続行するという要件に遭遇します。
これで、pexの実行段階後にpexが受信したデータを静かに使用できます

もう1つの重要なことは、ハードページにインストールされているモジュールの静的ページとそのバージョンの動作をチェックすることです。 次の部門を追加します。
 [Require] data = "core:0.2, template:0.1, mysql:0:1, lang:0.2"; 

モジュールには0.2以上のバージョンのローダーが必要であることがわかります(これが「擬似モジュール」である理由です:マニフェストとバージョンの両方を持ち、他のモジュールと同様にアクセスできますが、「ハードワイヤード」ですシステム)、 MySQLデータベースを操作するためのモジュール、別のlangモジュール(エンコード、日時形式などを担当します)、およびページング用のモジュール。

ただし、「キュー」はパフォーマンスにあまり影響しません。開発者が何らかの方法でそれに依存するすべてのモジュールを指定するのは面倒です。 したがって、モジュラーメソッドの実行の「レベルのカップル」を作成するのが最も合理的です。
これらは、マニフェスト内の新しい部門になります。最初に、 [Prev] 、既知の[Run][After]、および[Finish]を持つメソッドが実行されます。

たとえば、pexモジュールマニフェストの一部を取得します。
 [Prev] run = "getGroup()"; require = "auth"; [Run] run = "template()"; [After] run = "nodesContainers()" 

最初に、 [Prev]ステージで、ユーザーが属するグループの権限を受け取りますが、これは認証モジュールがユーザー自身に関するデータを受け取った後にのみです。 次に、彼はtemplate()メソッドを実行します。このメソッドでは、たとえば、現在のユーザーがサイトを閲覧できるかどうかを確認します(ただし、他のモジュールにも作業を任せます)。
そしてその後-彼はいわゆるnodesContainersのテンプレートをチェックし、いくつかの権限が必要なテンプレートのセクションにアクセスします(結局、前の段階では、異なるモジュールがそのようなセクションを追加でき、処理されません)。

また、いくつかのモジュールが必要とする可能性のあるライブラリを忘れないでください。別のセクションを追加します。
 [Include] dirs = ""; 

ブートローダーはこの部門をチェックし、必要に応じてフォルダーのすべてのファイルを含めます。

最後に、 index.phpに次のようなものがあります。
 include "core/lib/module/mod.php"; //     include "core/engine.php"; //  -  Engine::loadLibs(); //       (  ) session_start(); //  $engine = new Engine(); //   $engine->enableModules(); //    $engine->modTemplates(); //     ModError::printErrors(); //   (      ,   ) 


最後に何がありますか?


モジュール読み込みのほぼ完全な自動化、完全なシステムモジュール化。 データベースの操作-mysqlモジュール。 テンプレートの操作- テンプレートモジュール。 ナビゲーションバーはスピードバーモジュールです。 必要なし フォルダーを削除します。
<![Mod = speedbar]> Speedbar here:<!Speedbar> <![/ Mod = speedbar]>のような便利なテンプレートコンテナを使用すると、モジュールがあります-動作し、セクションが表示されます。 モジュールなし-セクションはまったく表示されません。

この原則に基づいて、既存のモジュールと特別に作成されたモジュールを使用して、複雑なサイトを構築できます。 どのモジュールでも他のモジュールを使用でき、直接コードを実行するとほぼ100%の柔軟性が得られます。 Ajaxが必要ですか? すべてが完了して準備されるまで待機するモジュールを作成し、最後にテンプレートの表示をキャンセルして必要なものだけを表示します。

もちろん、この方法にも欠点があります:キューが常に構築されるため、パフォーマンスが低下し、モジュールが必要な場所に移動できなくなる可能性があり、これに直面している平均的なユーザーは、いくつかのモジュールを接続しようとして、すべてを正しくドロップします。
しかし、仕事が始まって以来、私は幅広い聴衆をターゲットにしておらず、発明されたものはすべて自分だけに使用されています。 そして、「それ」は私にぴったりです。

このメソッドの現在のモデルは私のページで見ることができ(リンクはプロファイルにあります)、ソースコードはGitHubリポジトリにあります

ご関心をお寄せいただきありがとうございます。誰かがこのトピックに興味がある場合は、理論から実践への移行に関するトピックを作成します。

Source: https://habr.com/ru/post/J133650/


All Articles