首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >redbeanphp和表前缀

问redbeanphp和表前缀
EN

Stack Overflow用户
提问于 2013-01-03 18:04:17
回答 3查看 2.1K关注 0票数 4

我在我的php项目中使用Redbeanphp ( http://redbeanphp.com/ )。我想为我的表使用一个表前缀。

Redbeanphp从3.0版本开始不支持表前缀。但是我想在我的项目中扩展Redbeanphp来支持表格前缀。

我不想修改redbeanphp代码。但如果没有解决方案,我会这么做。

我已经尝试替换Redbeanphp的QueryWriter,但QueryWriter类并不总是相同的(它取决于我的数据库的类型)。

做到这一点的最好方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-04 04:01:57

我现在得到了回应,所以我对自己说了算。

一旦初始化了redbean,您就可以配置新的工具箱。redbean中的工具箱处理3个重要的对象:查询编写器、Redbean OODB和数据库适配器。您可以使用R::$toolbox访问当前的redbean工具箱

您可以执行以下代码:

代码语言:javascript
复制
R::configureFacadeWithToolbox(new RedBean_ToolBox(R::$redbean, R::$adapter, R::$writer));

这段代码什么也不做。因为您使用新的工具箱配置Redbean,但是使用相同的OODB、相同的数据库适配器和相同的查询编写器。但是在这段代码中,您可以用自己的对象替换其中的一个对象。

例如,将编写器替换为虚拟编写器:

代码语言:javascript
复制
$writer = new MyQueryWriter();
R::configureFacadeWithToolbox(new RedBean_ToolBox(R::$redbean, R::$adapter, $writer));

问题如下:

  • 您希望用自己的查询编写器替换查询编写器以处理表前缀
  • 查询编写器类并不总是相同的。Redbean使用5个类作为查询编写器。类取决于数据库类型。例如,如果您使用的是Mysql数据库,则查询编写器类是RedBean_QueryWriter_MySQL
  • You不想写入整个查询编写器。

Redbean查询编写器可能的类包括:

  • RedBean_QueryWriter_CUBRID
  • RedBean_QueryWriter_MySQL
  • RedBean_QueryWriter_Oracle
  • RedBean_QueryWriter_PostgreSQL
  • RedBean_QueryWriter_SQLiteT

所以,这就是我的解决方案。我写了5个小类。

代码语言:javascript
复制
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函数很简单:

代码语言:javascript
复制
function prefix($table) {
    return "my_prefix_$table";
}

所以现在,在我们的代码中。我们可以使用数组将Redbean查询编写器类映射到我们自己的类并替换它。我们在这里:

代码语言:javascript
复制
$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方法,我们为数据库中的每个表名添加一个前缀。

票数 7
EN

Stack Overflow用户

发布于 2013-01-05 06:28:53

当我想在Wordpress中使用RedBean时,我遇到了这个问题。我的解决方案是创建另一个类( "wordpress redbean“的WPR),如下所示:

代码语言:javascript
复制
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}');

在这两种情况下,{博客}被转换为wp_blogs

票数 0
EN

Stack Overflow用户

发布于 2013-01-08 03:14:22

法师

我和你有同样的问题。我尝试了您的解决方案,但无法使其工作。我编写了几个函数,用于在表名和表名之间添加前缀和后缀,我认为这些函数在我的例子中是可行的,但我仍然希望按照您的方式工作,因为它将更加透明。我使用无前缀的表名来进行读写。

我注意到在RedBean中没有现成的Oracle支持,所以我为每个类名添加了检查,以避免错误:

代码语言:javascript
复制
if (class_exists('RedBean_QueryWriter_MySQL', false)) {
    class MyMysqlQueryWriter extends RedBean_QueryWriter_MySQL {
    ...
}

检查应该有效,在加载前缀代码时,我在我的MySQL (我正在使用的)块中得到了输出到我的日志中。

另外,在结尾处你写道:

代码语言:javascript
复制
$class = $writerMapping(get_class(R::$writer));

但你的意思可能是:

代码语言:javascript
复制
$class = $writerMapping[get_class(R::$writer)];

根据一些调试,我的R::$writer在configureFacadeWithToolbox之后被更改了,但是由于某种原因,表名没有被转换,并且我的自定义safeTable函数中的任何东西都没有被执行。

如果你能提供更多关于你是如何测试你的方法的信息,或者我可能会遗漏什么,我会很高兴听到的。

(很抱歉,这条消息不是对您问题的回答,但我真的找不到任何其他方式向您发送消息或对您的回答发表评论。该死的堆栈溢出!(开个玩笑,我很喜欢。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14136621

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档