php - 将查询传递给使用第二个数据库的 module_hook

标签 php drupal drupal-7 drupal-modules

我想使用另一个数据库连接,它使用我自己的名为“连接器”的模块中的 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 &#039;drupal.registration&#039; doesn&#039;t exist: SELECT registration.* FROM {registration} registration WHERE (id = :db_condition_placeholder_0) ; Array ( [:db_condition_placeholder_0] =&gt; 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/

相关文章:

drupal - Drupal 7中的多个并发数据库连接

php - 在 Drupal 上连接数据库表

drupal-7 - EntityFieldQuery 多个备选条件

PHP MYSQL 执行且仅当 php session 变量存在时执行

java - Drupal Hook 是 Java 中事件处理的实现吗?

php - 在 Drupal 7 中使用 RESTful 模块创建用户 API

php - 创建新主题后出现 Drupal 错误, undefined variable : hide_site_name and other similar error

php - 在 PHP 函数中使用数组作为默认参数

php - 剥离一切,除了 PHP 中的字母数字和欧洲字符

php - 将 Zend Framework 从版本 X 升级到版本 Y