2

問題が発生しましたが、これが正常な動作なのか、何か間違った書き方をしたのかわかりません。基本クラスに、特定のクラスのすべての新しいインスタンスのプロキシを作成することにより、特定のクラスにグローバルフィルターを適用するメソッドがあります。私がそれについて行くことを計画した方法は次の通りです:

  1. static $global_filterフィルタリングしたいクラスに(プロキシ)をアタッチします。これにより、基本クラスが拡張されます。object
  2. ロードメカニズムを介して、新しいインスタンス化時に実際のクラスの代わりにプロキシを返します(これにより、メソッド呼び出しがマスクされ、それに応じてフィルターが適用されます)

ただし、手順1static $global_filterで行き詰まり、フィルタリングしたい子孫クラスに割り当てようとすると、基本クラスobjectにも同じ割り当てが割り当てられ、それ以降のすべてが中断されるようです。

関連するコードについては、以下を参照してください。

class object {

    public static $global_filter;

    public function _filterGlobal($class, $method, $callback) {
        if ( !is_object($class::$global_filter) ) {
            $class::$global_filter = new filterable(null);
            # Replace the object being called with the new proxy.
        }
        var_dump($class);
        var_dump($class::$global_filter); // `filterable`
        var_dump(\core\blueprint\object::$global_filter); // Returns same as line above
        die();
        return $class::$global_filter->_add($method, $callback);
    }

}

$class::$global_filterと(基本クラス)の両方\core\blueprint\object::$global_filterが同じインスタンスを返しています。私object::$global_filterはnullになると思っていましたが。

一貫性を維持するためにレイトスタティックバインディングを使用していません(単一オブジェクトフィルターとグローバルフィルターの両方が非静的にほとんど同じ方法で呼び出されます)。

この質問は関連しているようです

どんな助けでも大歓迎です:)

編集、完全な例

これは具体的なクラスになりますmodelobject

<?php
use core\blueprint\model;
class modelMock extends model {
    protected $schema = array();
    public function method($test) {
        return $test;
    }
}

これは別のオブジェクト(コントローラーなど)であり、これも拡張されobjectます。のすべての新しいインスタンスにフィルターを適用しますmodel

<?php
use core\blueprint\object;
class objectMock extends object {

    public function applyFilters() {
        $this->_filterGlobal('core\blueprint\model', 'method', function($self, $chain) {
            $chain->params[0] = 'new param'; // adjust the paramters
            return $chain->next();
        });
    }

}
4

3 に答える 3

1

これがあなたの助けになるかどうかはわかりません:

class a {
   public static $type;

   public static function setType($class, $newType) {
      $class::$type = $newType;
      var_dump($class::$type);
   }
}
class b {
   public static $type = 'myType';
}

var_dump(b::$type);
a::setType('b', 'yourType');
var_dump(a::$type);

具象クラスに静的プロパティを定義していない可能性があります。

于 2012-11-19T12:06:16.583 に答える
1

フィルタリングしたい子孫クラスに静的 $global_filter を割り当てようとすると、基本クラス オブジェクトも同じ割り当てを取得します

はい、確かにこれは起こります。本質的に静的プロパティは、クラスの名前空間内に制約されたグローバル変数です。グローバル変数で問題が発生することは、多くの場合、最適なソリューションを使用していないことを示しています。

問題を解決するには、フィルターを (非静的) プロパティにすることができます。

$class->$filter = new Whatever();

しかし、いつものように、ローマに通じる道は他にもあります。別の方法を探すことをお勧めします。

于 2012-11-19T11:51:22.267 に答える
1

助けてくれてありがとう、今朝少し時間をかけて問題を解決することができました。ちょっとした回避策ですが、次のようになります。

public function _filterGlobal($class, $method, $callback) {
    if ( !is_object($class::$global_filter[$class]) ) {
        $class::$global_filter[$class] = new filterable(null);
        # Replace the object being called with the new proxy.
    }
    return $class::$global_filter[$class]->_add($method, $callback);
}

したがって、基本的に、明示的に定義せずに子クラスで機能する一意の静的変数を取得するには、子のクラス名をキーとして格納する配列を使用し、ゲッターを介してこれらの変数にアクセスできます。

于 2012-11-19T21:09:32.613 に答える