もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

CakePHP3のfindではバッククォートが使われない対応

Cakephpネタ。

レガシーなシステムとかだと、MySQL予約語とかがカラム名に設定されてたりする(レガシー関係ないか・・・)

実際自分が携わっている案件でも、

CREATE TABLE `customer_profile_options` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `customer_id` int(10) unsigned NOT NULL COMMENT,
  `key` varchar(128) NOT NULL COMMENT '項目名',
  `value` text NOT NULL COMMENT '値',
  `created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  CONSTRAINT `customer_profile_options_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

みたいなイメージの縦持ちテーブルがあって、keyはMySQL予約語として使われている。

QueryBuilderとかでSQL組み立ててinsertとかすると

INSERT INTO customer_enquete_options (id, enquete_master_id, key, value, created) VALUES (?, ?, ?, ?, ?);

みたいな感じで、SQLが組み立てられる。

CakePHP2系までは各カラムにバッククォートが適用されて上記のinsert文は問題なく発行できた。

ただ、CakePHP3では上記のようにデフォルトでバッククォートがつかないようなので、SQL syntaxエラーが発生していた。

うーんうーん。とCakeのDatabaseDriverあたりのクラスを見てみると Cake\Database\Driver.phpで以下のような文を発見。

<?php

..
        $this->_config = $config;
        if (!empty($config['quoteIdentifiers'])) {
            $this->enableAutoQuoting();
        }

それっぽい。

公式で確認するとたしかにあった。

quoteIdentifiers あなたがテーブルやカラム名予約語特殊文字を使用している場合は true に設定します。 この設定を有効にすると、SQL を生成する際に クエリービルダー によって引用符で囲まれたクエリーが生成されます。 これはクエリーを実行する前に横断的に処理を行う必要があるため、パフォーマンスを 低下させることに注意してください。

ということで、config/app.phpのDatasources項目にある quoteIdentifierstrue にすると、正常にバッククォートが適用されていた。

公式の文で注意されていたパフォーマンスを低下させるっていうのがどの程度のものなのかビクビクするけど、ビクビクするくらいならばテーブル設計やり直したほうが良さそう。。。

とにかく、設計より設定って感じだった。