我想使用另一个数据库连接,它使用我自己的名为“连接器”的模块中的 Hook 查询数据库。该 Hook 应采用一个查询参数,该查询应在切换回主 Drupal 7 数据库之前使用辅助数据库执行。问题似乎是查询以某种方式为(主)Drupal 数据库生成(因为它是在切换到辅助数据库之前创建的),即使 SQL 本身对我来说看起来很好。我在这里做错了什么?
钩子(Hook):
function connector_api_db($query) {
$result = [];
$database_info = array(
'database' => variable_get('connector_db_name'),
'username' => variable_get('connector_db_user'),
'password' => variable_get('connector_db_pwd'),
'host' => variable_get('connector_db_host'),
'driver' => 'mysql',
);
Database::addConnectionInfo('secondary_db', 'default', $database_info);
db_set_active('secondary_db'); // Initialize the connection
/* This actually works but I can here not use my own query as a parameter in this function. Not what I want. */
//$query = db_select('registration')->fields('registration')
//->condition('id', 46, '=');
echo $query->__toString() . "<br />"; /* Get query string */
var_dump($query->getArguments()); /* Get the arguments passed to the string */
$result = $query->execute()->fetchAssoc();
echo "<pre>";
print_r($result);
echo "</pre>";
db_set_active(); // without the paramater means set back to the default for the site
drupal_set_message(t('The queries have been made.'));
return $result;
}
调用钩子(Hook):
$query = db_select('registration')
->fields('registration')
->condition('id', 46, '=');
$response = module_invoke('connector', 'api_db', $query);
这导致:
SELECT registration.* FROM {registration} registration WHERE (id = :db_condition_placeholder_0)
array(1) { [":db_condition_placeholder_0"]=> int(46) }
Additional uncaught exception thrown while handling exception.
Original
PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'drupal.registration' doesn't exist: SELECT registration.* FROM {registration} registration WHERE (id = :db_condition_placeholder_0) ; Array ( [:db_condition_placeholder_0] => 46 ) in connector_api_db() (line 70 of /<path-to-drupal>/drupal-7.61/modules/connector/connector.main.inc).
最佳答案
严格来说,这不是答案,而是建议。
问题是你的钩子(Hook)收到了一个已经用原始数据库连接构建的$query
,这解释了错误。为了有效,db_set_active()
应该在调用查询构造函数之前调用。
否则,您将不得不覆盖 Select 类及其父类 Query 的构造函数,或者更准确地说,为 Select 语句“重建”查询构建器实例 (如果您需要范围查询等,可能还有其他人)。
此外,除非明确要求在这种情况下提供专用钩子(Hook),否则没有必要。
例如,做这样的事情会更简单:
connector.module :
/**
* Implements hook_init()
*
* Adds secondary database connection information.
*/
function connector_init() {
$database_info = array(
'database' => variable_get('connector_db_name'),
'username' => variable_get('connector_db_user'),
'password' => variable_get('connector_db_pwd'),
'host' => variable_get('connector_db_host'),
'driver' => 'mysql',
);
Database::addConnectionInfo('secondary_db', 'default', $database_info);
}
/**
* Switches from primary to secondary database and the other way round.
*/
function connector_switch_db($db_key = 'secondary_db') {
return db_set_active($db_key);
}
示例:
// Set secondary db active.
$primary_db_key = connector_switch_db();
$query = db_select('registration')
->fields('registration')
->condition('id', 46, '=');
$result = $query->execute()->fetchAssoc();
// Switch back to the primary database.
connector_switch_db($primary_db_key);
这种更软的方法还可以防止像 (...)->execute()->fetchAssoc()
这样的硬编码,并让实现自由执行并根据需要获取结果。
关于php - 将查询传递给使用第二个数据库的 module_hook,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53969958/