Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@tatsuo-iriyama

CakePHP3 ORMのWHERE句で、date_formatで指定した "Y" が "y" になってしまう

TL;DR

  • DATE_FORMATで %Y を使用する場合は、以下を参考にする
    • where句でコールバック関数とクロージャーを使用し、eqメソッドを使用する
$createdFormat = $query->func()->date_format([
    'created'    => 'identifier',
    "'%Y-%m-%d'" => 'literal'
]);
$query->where(function ($exp) use ($createdFormat, $created) {
    return $exp->eq($createdFormat, $created);
});

前提

  • PHP
    • 7.3.11
  • CakePHP
    • v3.6.14

事象

1.
ORM: $query->where(["DATE_FORMAT(created, '%Y-%c') = " => $date])
SQL: WHERE DATE_FORMAT(created, '%y-%c') = :c0
################
2.
ORM: $query->where(["DATE_FORMAT(created, '%Y-%c') = ${date}"])
SQL: WHERE DATE_FORMAT(created, '%Y-%c') = 2020-8)
  • 上記の通り、連想配列によるデータの渡し方では、発行されるSQLのフォーマットが、Yy になってしまう
  • 変数展開による渡し方では、発行されるSQLのフォーマットは、Y のまま

原因

  • 巡りめぐってQueryExpression::_parseCondition()を参照し、そこでstrtolowerを行ってるため
  • 以下対象コードの一部抜粋
    protected function _parseCondition($field, $value)
    {
        $operator = '=';
        $expression = $field;
        $parts = explode(' ', trim($field), 2);

        if (count($parts) > 1) {
            list($expression, $operator) = $parts;
        }

        $type = $this->getTypeMap()->type($expression);
        $operator = strtolower(trim($operator));

        ...

        return new Comparison($expression, $value, $type, $operator);
    }

対策

  1. date_formatで指定したいカラムを、別でフォーマット化する
  2. WHERE句でコールバック関数とeqメソッドを使って条件に追加する
$createdFormat = $query->func()->date_format([
    'created'    => 'identifier',
    "'%Y-%m-%d'" => 'literal'
]);
$query->where(function ($exp) use ($createdFormat, $created) {
    return $exp->eq($createdFormat, $created);
});
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?