2

schmittjoh / cg-libraryは私が必要としているもののようですが、ドキュメントはまったくありません。

このライブラリは、PHPコードを生成するために一般的に必要ないくつかのツールを提供します。その強みの1つは、動作を備えた既存のクラスの拡張にあります。

与えられAたクラス:

class A {}

Aもちろん、実行時に、いくつかのキャッシュメカニズム、クラスを使用して、特定のインターフェイスを実装するように変更したいと思います。

interface I
{
    public function mustImplement();
}

...クラスmustImplement()内のメソッドの「デフォルト」実装を使用します。A

4

5 に答える 5

5

注: OPにはPHP 5.3が必要です(以前はそのようにタグ付けされていませんでした)。この質問はPHP5.4の一般的な概要です。

これを行うには、インターフェースを定義し、それらのインターフェースのデフォルトの実装を含むトレイトを追加します。

次に、新しいクラス定義を作成します。

  • 基本クラスから拡張し、
  • そのインターフェースを実装し、
  • デフォルトの特性を使用します。

例については、PHPの特性–実際の例/ベストプラクティスを参照してください。

そのクラス定義コードを簡単に生成して、それとそれを保存するか、includeそのまま保存することができますeval

構成するすべての情報(この場合は基本クラス名とインターフェース)を含む新しいクラス名を作成すると、重複するクラス定義を簡単に作成することを防ぐことができます。

これは、runkitのようなPHP拡張機能がなくても機能します。serializeプレイに参加すると、シリアル化/逆シリアル化できる場合に備えて、実行時に既存のオブジェクトを新しいインターフェイスでオーバーロードすることもできます。

これを実装しているコード例は、次の場所にあります。

于 2012-09-29T08:31:59.877 に答える
5

Role Object パターンと古き良き集約を使用することもできます。

すべてのビジネス ロジックを含むスマート エンティティを用意する代わりに、それらをダムにし、すべてのビジネス ロジックを役割に移動して、ダム エンティティを集約します。あなたの行動は、役割の中に住む一流の市民です。

例:

interface BannableUser
{
    public function ban();
}

1 つの特定の動作を持つインターフェイスを持つことは、インターフェイス分離の原則に従います。また、アプリケーション固有の動作のコレクションを持つエンティティよりも個々の動作を再利用する可能性が高いため、再利用の可能性が大幅に増加します。

これを実装するには、適切なロール クラスを作成します。

class BannableUserRole implements BannableUser
{
     private $user;

     public function __construct(User $user)
     {
         $this->user = $user;
     }

     public function ban()
     {
         $this->user->isBanned = true;
     }
}

User エンティティはまだありますが、すべての動作が完全に取り除かれています。基本的には、Getter と Setter、またはパブリック プロパティの単なるバッグです。それはあなたのシステム何であるかを表しています。インタラクション部分ではなく、データ部分です。インタラクションは現在、ロール内にあります。

class User
{
    public $isBanned;

    // … more properties
}

ある種の Web UI があると仮定すると、コントローラーで次のことができます。

class BanUserController implements RequestHandler
{
    // …

    public function handleRequest(Request $request)
    {
        $userId = $request->getVar('user_id');
        $user = $this->userRepository->findById($userId);
        $bannableUser = new BannableUserRole($user);
        $bannableUser->ban();
    }
}

ユーザーの実際の検索と役割の割り当てを UseCase クラスに移動することで、これをさらに分離できます。それをコンテキストと呼びましょう:

class BanUserContext implements Context
{
    public function run($userId)
    {
        $user = $this->userRepository->findById($userId);
        $bannableUser = new BannableUserRole($user);
        $bannableUser->ban();
    }
}

これで、すべてのビジネス ロジックがモデル レイヤー内にあり、ユーザー インターフェイスから完全に分離されました。コンテキストは、システムが行うことです。コントローラーは、適切なコンテキストにのみ委任します。

class BanUserController implements RequestHandler
{
    // …

    public function handleRequest(Request $request)
    {
        $this->banUserContext->run($request->getVar('user_id'));

    }
}

以上です。Runkit や同様のハッカーは必要ありません。上記は、さらに調査したい場合に備えて、 Data Context Interactionアーキテクチャ パターンの簡略化されたバージョンです。

于 2012-09-30T10:05:59.260 に答える
0

Runkit拡張機能はあなたを助けることができます

Runkit_Sandbox — Runkit Sandbox Class -- PHP Virtual Machine
Runkit_Sandbox_Parent — Runkit Anti-Sandbox Class
runkit_class_adopt — Convert a base class to an inherited class, add ancestral methods when appropriate
runkit_class_emancipate — Convert an inherited class to a base class, removes any method whose scope is ancestral
runkit_constant_add — Similar to define(), but allows defining in class definitions as well
runkit_constant_redefine — Redefine an already defined constant
runkit_constant_remove — Remove/Delete an already defined constant
runkit_function_add — Add a new function, similar to create_function
runkit_function_copy — Copy a function to a new function name
runkit_function_redefine — Replace a function definition with a new implementation
runkit_function_remove — Remove a function definition
runkit_function_rename — Change the name of a function
runkit_import — Process a PHP file importing function and class definitions, overwriting where appropriate
runkit_lint_file — Check the PHP syntax of the specified file
runkit_lint — Check the PHP syntax of the specified php code
runkit_method_add — Dynamically adds a new method to a given class
runkit_method_copy — Copies a method from class to another
runkit_method_redefine — Dynamically changes the code of the given method
runkit_method_remove — Dynamically removes the given method
runkit_method_rename — Dynamically changes the name of the given method
runkit_return_value_used — Determines if the current functions return value will be used
runkit_sandbox_output_handler — Specify a function to capture and/or process output from a runkit sandbox
runkit_superglobals — Return numerically indexed array of registered superglobals
于 2012-09-29T08:31:35.290 に答える
0

あなたが見ることができます:https://github.com/ptrofimov/jslikeobject

作成者は、継承をサポートする動的な JS に似たオブジェクトを実装しました。

しかし、それは本当の命題というよりは冗談のようなものです。

于 2013-01-08T18:28:07.603 に答える