Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
redbeanphp和表前缀_Php_Orm_Redbean - Fatal编程技术网

redbeanphp和表前缀

redbeanphp和表前缀,php,orm,redbean,Php,Orm,Redbean,我在php项目中使用redbeanppp()。我想为我的表使用一个表前缀 由于版本3.0,Redbeanphp无法支持表前缀。但是我想在我的项目中扩展Redbeanphp以支持表前缀 我不想修改redbeanphp代码。但如果没有解决办法,我会这么做 我已经尝试替换Redbeanphp的QueryWriter,但QueryWriter类并不总是相同的(这取决于我的数据库类型) 最好的方法是什么?我现在得到了答案,所以我自己回答 一旦redbean被初始化,您就可以配置一个新的工具箱。redbea

我在php项目中使用redbeanppp()。我想为我的表使用一个表前缀

由于版本3.0,Redbeanphp无法支持表前缀。但是我想在我的项目中扩展Redbeanphp以支持表前缀

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

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


最好的方法是什么?

我现在得到了答案,所以我自己回答

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

您可以通过以下代码执行此操作:

R::configureFacadeWithToolbox(new RedBean_ToolBox(R::$redbean, R::$adapter, R::$writer));
此代码不起任何作用。因为您使用新的工具箱配置Redbean,但使用相同的OODB、相同的数据库适配器和相同的查询编写器。但在这段代码中,您可以用自己的对象替换其中一个对象

例如,用虚拟写入程序替换写入程序:

$writer = new MyQueryWriter();
R::configureFacadeWithToolbox(new RedBean_ToolBox(R::$redbean, R::$adapter, $writer));
问题如下:

  • 您希望用自己的查询编写器替换查询编写器以处理表前缀
  • 查询编写器类并不总是相同的。Redbean为查询编写器使用5个类。该类取决于数据库类型的类型。例如,如果使用Mysql数据库,则查询编写器类是
    RedBean\u QueryWriter\u Mysql
  • 您不想编写整个查询编写器
Redbean查询编写器可能的类有:

  • 红豆作家库布里德
  • RedBean\u QueryWriter\u MySQL
  • 红豆作家甲骨文
  • RedBean\u QueryWriter\u PostgreSQL
  • RedBean\u QueryWriter\u 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);
   }

} 
如您所见,每个类都扩展了一个红豆查询编写器类。我们重写了
safeTable
方法。Redbean总是在表名上使用
safeTable
前缀
功能很简单:

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));

瞧。现在红豆将使用你自己的作家,你可以做你想做的!通过我们的
safeTable
方法,我们为数据库中的每个表名添加一个前缀。

当我想在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);
我还希望这个类使用与我的“常规”红豆类不同的数据库,因此我在其中有selectDatabase()调用。如果你不需要它们,就把它们注释掉

它所做的是充当redbean的代理,但每次输入时,它都会检查像{this}这样的子字符串,并将其扩展为带有前缀的完整数据库名。以下是您的用法示例:
$my_blog=WPR::find({blogs}',domain=?',array('mydomain.com')
$allowed_hosts=WPR::getCol('SELECT domain FROM{blogs}')

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

Magus

我和你有同样的问题。我试过你的解决办法,但没能奏效。我编写了两个函数,用于将我的对象名和前缀添加到表名中,然后返回,我认为这在我的情况下会起作用,但我仍然希望您的方式能够起作用,因为这样会更加透明。我有固定的表名,用于阅读和写作

我注意到Oracle支持在RedBean中不可用,因此我为每个类名添加了检查以避免错误:

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)];
根据一些调试,我的
R::$writer
configureFacadeWithToolbox
之后发生了更改,但是由于某些原因,表名没有被转换,自定义
safeTable
函数中的任何内容都没有被执行

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


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

哦,是的,您是对的,我的代码中有错误。我纠正了这一点。但我的解决方案对我来说是可行的,每次redbean需要生成表名(在写入、读取和表创建中)时,我的查询编写器的safeTable方法都会被redbean调用。您能添加用于创建连接的代码并执行读/写操作吗?也许这里有一些重要的东西。代码非常具体,所以我把代码放在一个粘贴箱中:这段代码来自我的一个项目。你可以在这里找到整个课程和项目:非常感谢,我来看看。我正在将此集成到现有的解决方案中,如果我发现有什么有趣或值得关注的事情,我会及时与您联系。@EISKI您应该创建一个新的redbean实例作为redbean_工具箱的第一个参数:
R::configureFacadeWithToolbox(new redbean_ToolBox(new redbean_OODB($writer),R:$adapter,$writer))
safeTable因使用esc而贬值,问题是它使用相同的函数转义列名和表名。这意味着,如果覆盖esc,所有列也将获得前缀。