4

私は自分のphpプロジェクトでRedbeanphp(http://redbeanphp.com/ )を使用しています。そして、テーブルにテーブルプレフィックスを使用したいと思います。

バージョン3.0以降、Redbeanphpはテーブルプレフィックスをサポートできません。しかし、プロジェクトでテーブルプレフィックスをサポートするようにRedbeanphpを拡張したいと思います。

redbeanphpコードを変更したくありません。しかし、解決策がない場合は、それを行います。

RedbeanphpのQueryWriterを置き換えようとしましたが、QueryWriterクラスが常に同じであるとは限りません(データベースのタイプによって異なります)。

それを行うための最良の方法は何ですか?

4

3 に答える 3

7

返事が来たので、自分なりに答えます。

redbean が初期化されると、新しいツールボックスを構成できます。redbean のツールボックスは、クエリ ライター、Redbean OODB、およびデータベース アダプターの 3 つの重要なオブジェクトを処理します。現在の redbean ツールボックスにアクセスするには、R::$toolbox

このコードを実行できます:

R::configureFacadeWithToolbox(new RedBean_ToolBox(R::$redbean, R::$adapter, R::$writer));

このコードは何もしません。新しいツールボックスを使用して Redbean を構成するが、同じ OODB、同じデータベース アダプター、および同じクエリ ライターを使用するためです。ただし、このコードでは、これらのオブジェクトの 1 つを独自のオブジェクトに置き換えることができます。

ライターをダミーのライターに置き換える例:

$writer = new MyQueryWriter();
R::configureFacadeWithToolbox(new RedBean_ToolBox(R::$redbean, R::$adapter, $writer));

問題は次のとおりです。

  • テーブルプレフィックスを処理するために、クエリライターを独自のクエリライターに置き換えたい
  • クエリ ライター クラスは常に同じではありません。Redbean は、クエリ ライターに 5 つのクラスを使用します。クラスはデータベースの種類によって異なります。たとえば、Mysql データベースを使用する場合、クエリ ライター クラスはRedBean_QueryWriter_MySQL
  • クエリ ライター全体を作成する必要はありません。

Redbean クエリ ライターの可能なクラスは次のとおりです。

  • RedBean_QueryWriter_CUBRID
  • RedBean_QueryWriter_MySQL
  • RedBean_QueryWriter_Oracle
  • RedBean_QueryWriter_PostgreSQL
  • RedBean_QueryWriter_SQLiteT

だから、これが私の解決策です。私は5つの小さなクラスを書きました。

class MyCubridQueryWriter extends RedBean_QueryWriter_CUBRID {

   public function safeTable($name, $noQuotes = false) {
      $name = prefix($name);
      return parent::safeTable($name, $noQuotes);
   }

} 

class MyMysqlQueryWriter extends RedBean_QueryWriter_MySQL {

   public function safeTable($name, $noQuotes = false) {
      $name = prefix($name)
      return parent::safeTable($name, $noQuotes);
   }

}

class MyOracleQueryWriter extends RedBean_QueryWriter_Oracle {

   public function safeTable($name, $noQuotes = false) {
      $name = prefix($name)
      return parent::safeTable($name, $noQuotes);
   }

} 

class MyPostgreSqlQueryWriter extends RedBean_QueryWriter_PostgreSQL {

   public function safeTable($name, $noQuotes = false) {
      $name = prefix($name)
      return parent::safeTable($name, $noQuotes);
   }

}

class MySQLiteTQueryWriter extends RedBean_QueryWriter_SQLiteT {

   public function safeTable($name, $noQuotes = false) {
      $name = prefix($name)
      return parent::safeTable($name, $noQuotes);
   }

} 

ご覧のとおり、各クラスは Redbean クエリ ライター クラスを拡張します。メソッドをオーバーライドしますsafeTable。Redbean は常にsafeTableテーブル名で使用します。prefix関数は単純です:

function prefix($table) {
    return "my_prefix_$table";
}

それでは、コードで。配列を使用して、Redbean クエリ ライター クラスを独自のクラスにマップし、それを置き換えることができます。ここにいます:

$writerMapping = array(
    'RedBean_QueryWriter_CUBRID' => 'MyCubridQueryWriter',
    'RedBean_QueryWriter_MySQL' => 'MyMysqlQueryWriter',
    'RedBean_QueryWriter_Oracle' => 'MyOracleQueryWriter',
    'RedBean_QueryWriter_PostgreSQL' => 'MyPostgreSqlQueryWriter',
    'RedBean_QueryWriter_SQLiteT' => 'MySQLiteTQueryWriter'
);

$class = $writerMapping[get_class(R::$writer)];
$writer = new $class(R::$adapter);

R::configureFacadeWithToolbox(new RedBean_ToolBox(R::$redbean, R::$adapter, $writer));

出来上がり。これで、Redbean は独自のライターを使用して、やりたいことを実行できます! このsafeTable方法では、データベース内のすべてのテーブル名にプレフィックスを追加します。

于 2013-01-03T20:01:56.687 に答える
0

魔術師、

私はあなたと同じ問題を抱えています。私はあなたの解決策を試しましたが、うまくいきませんでした。接頭辞とオブジェクト名をテーブル名に付けたり戻したりするための関数をいくつか書きましたが、これは私の場合はうまくいくと思いますが、より透過的であるため、あなたのやり方でうまくいきたいと思っています. 読み取りと書き込みに使用する接頭辞のないテーブル名があります。

RedBean ではすぐに使用できる Oracle サポートがないことに気付いたので、エラーを回避するために各クラス名のチェックを追加しました。

if (class_exists('RedBean_QueryWriter_MySQL', false)) {
    class MyMysqlQueryWriter extends RedBean_QueryWriter_MySQL {
    ...
}

チェックは機能するはずです。接頭辞コードをロードしているときに、MySQL(私が使用している)ブロック内のログに出力を取得しました。

また、最後に次のように書いています。

$class = $writerMapping(get_class(R::$writer));

しかし、あなたはおそらく次のことを意味していました:

$class = $writerMapping[get_class(R::$writer)];

いくつかのデバッグに基づいて、 myR::$writerは の後に変更されましたが、何らかの理由でテーブル名が変換されておらず、カスタム関数configureFacadeWithToolbox内で何も実行されていません。safeTable

メソッドをどのようにテストしたか、または私が見逃している可能性があるものについて、さらに情報を提供していただければ幸いです。

(このメッセージはあなたの質問への回答ではなくて申し訳ありませんが、あなたの回答にメッセージやコメントを送信する他の方法が本当に見つかりませんでした.くそースタックオーバーフロー!(冗談です、私はそれが大好きです.) )

于 2013-01-07T19:14:21.817 に答える
0

Wordpress で RedBean を使用したいときに、この問題に遭遇しました。私の解決策は、次のように別のクラス (「wordpress redbean」の WPR) を作成することでした。

class WPR {

    public static function __callStatic($method, $params)
    {
        global $wpdb;
        $prefix = $wpdb->base_prefix;

        foreach ($params as &$param)
            $param = preg_replace('/\{([a-zA-Z0-9_]+)\}/', $prefix . '$1', $param);

        // switch to wordpress database
        R::selectDatabase('WPR');

        // do the dang thing
        $res = call_user_func_array(array('R',$method),$params);

        // go back
        R::selectDatabase('default');

        // send it
        return $res;
    }
};

R::addDatabase('WPR', "mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASSWORD);

また、このクラスが「通常の」redbean クラスとは異なるデータベースを使用するようにしたかったので、そこに selectDatabase() 呼び出しを入れました。不要な場合はコメントアウトしてください。

これは、redbean へのプロキシとして機能しますが、入力ごとに {this} のような部分文字列をチェックし、プレフィックス付きの完全なデータベース名に展開します。使用例を次に示します: $my_blog = WPR::find('{blogs}', 'domain=?', array('mydomain.com'));または $allowed_hosts = WPR::getCol('SELECT domain FROM {blogs}');

この 2 つの場合、{blogs} は wp_blogs に変換されます

于 2013-01-04T22:28:52.603 に答える