別にPDOでアクセスしても文法上は問題ないのですが、Drupalが使用しているデータベースに情報を読み書きする場合は、より簡単にデータベース処理を書くことができます。なので、その詳細についてまとめました。
使い方事前準備
モジュール名をXXXとした際、XXX.info.yml
と同じフォルダにXXX.install
ファイルを作成します。そして、その中にスキーマ定義を記述します。
次は入力サンプルですが、おおよそフィーリングで書き方は掴めるでしょう。「$schema['HOGEHOGE']」と書けば、テーブル「HOGEHOGE
」が自動生成されます。
ややこしい点としては、Datetime型の名称がRDBによって多少異なるため、「type
」の書き方が若干冗長になってしまっていることがあります( CSSみを感じる)。
なお、スキーマ定義を変更した場合、モジュールの再インストールが必要になります。再インストールするとそのモジュールが使用していたテーブル情報が消えてしまうため、事前のバックアップが重要です。
<?php
/**
* スキーマ定義
*/
function simple_chat_schema() {
$schema['chat_talk_data'] = [
'description' => 'Logging chat data.',
'fields' => array(
'id' => array(
'description' => 'Talk ID',
'type' => 'serial',
'not null' => TRUE,
),
'message' => array(
'description' => 'Message',
'type' => 'varchar',
'length' => 4096,
'not null' => TRUE,
),
'name' => array(
'description' => 'User Name',
'type' => 'varchar',
'length' => 256,
'not null' => TRUE,
),
'date' => array(
'description' => 'Talk DateTime',
'mysql_type' => 'timestamp',
'pgsql_type' => 'timestamp',
'sqlite_type' => 'datetime',
'length' => 256,
'not null' => TRUE,
),
),
'primary key' => array('id'),
];
return $schema;
}
クエリの叩き方
事前準備が完了していれば、Drupalが使用するデータベース内に、設定したテーブルが作成されているはずです。後は、テーブル名を指定してRDBを使用できます。
なお、SELECT文を発行する際はdb_queryの方が高速ですが、db_selectの方がより簡潔にクエリを書くことができます。
// db_queryは任意のSQLを実行する
db_query("INSERT INTO {sample_table} (message, name) VALUES('{message}','{name}')");
// ただしセキュリティ上の問題から、置き換え処理が推奨されている
db_query("INSERT INTO {sample_table} (message, name) VALUES(:message,:name)", [':message' => $message, ':name' => $name]);
// 条件を指定して削除する例
db_query("DELETE FROM {sample_table} WHERE id=:id", [:id => 3]);
// db_selectはSELECT文しか実行できないが、メソッドチェーンを利用して書ける
// ここで「'n'」はテーブル名の別名で、SQLにおける「AS」のようなもの
$result = db_select('node', 'n')
->fields('n', array('nid'))
->condition('type', $type)
->orderBy('nid')
->execute();
// fieldsはでSELECTする列をarray型で指定し、conditionで条件を指定します
// (orderBy、limitはSQLと同じ意味なので割愛)
$select = db_select('node', 'n')
->fields('n', ['nid', 'sticky', 'created'])
->condition('n.promote', 1)
->condition('n.status', 1, '=')
->condition('n.age', 20, '>=')
->condition('n.tail', 180, '<=')
->condition('n.type', ['dog', 'cat', 'monkey'], 'IN')
->condition('n.weight', [50, 80], 'BETWEEN')
->orderBy('n.sticky')
->orderBy('n.created', 'DESC')
->limit(5)
->execute();
※余談ですが、MySQLで日付情報(timestamp型)を書き込む際は「文字列として」書き込むらしいですね……しかもタイムスタンプの情報がないので、UTCで書き込み・任意のタイムゾーンで読み出す処理を書くのに苦労しました。Drupalにおいて、ユーザーが使用しているタイムゾーンは「drupal_get_user_timezone()
」で取得でき、DateTimeZone型にするには「new DateTimeZone(drupal_get_user_timezone());
」とします
db_selectもdb_queryもDrupal 9.0で削除予定……だと……!?
Deprecated
as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call
select() on it. For example, $injected_database->select($table, $alias, $options);
Deprecated
as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call
query() on it. For example, $injected_database->query($query, $args, $options);
参考
- 閲覧数 2131
コメントを追加