CakePHP 3.0->;在查找条件之间

CakePHP 3.0->;在查找条件之间,cakephp,orm,cakephp-3.0,Cakephp,Orm,Cakephp 3.0,是否可以在CakePHP2.5中这样的条件下执行“介于和之间”的操作? 在CakePHP2.5中,我编写了如下内容 'conditions' => ['start_date BETWEEN ? AND ?' => ['2014-01-01', '2014-12-32']] 我如何迁移它 另外,我会写一些 'conditions' => [ '? BETWEEN start_date AND end_date'] => '2014-03-31'] 表达 Beween表达

是否可以在CakePHP2.5中这样的条件下执行“介于和之间”的操作? 在CakePHP2.5中,我编写了如下内容

'conditions' => ['start_date BETWEEN ? AND ?' => ['2014-01-01', '2014-12-32']]
我如何迁移它

另外,我会写一些

'conditions' => [ '? BETWEEN start_date AND end_date'] => '2014-03-31']
表达 Beween表达式受开箱即用支持,但它们仅支持第一种情况,无需额外修改:

$Query = $Table
    ->find()
    ->where(function($exp) {
        return $exp->between('start_date', '2014-01-01', '2014-12-32', 'date');
    });
如果您想通过between方法处理第二种情况,那么您必须将所有值作为表达式传递,这很容易出错,因为在这种情况下,它们将不受转义/参数绑定的约束,您必须自己进行处理(这不是推荐的!请参阅中的安全说明),大致如下:

use Cake\Database\Expression\IdentifierExpression;
use Cake\Database\Expression\QueryExpression;
use Cake\ORM\Query;

// ...

$Query = $Table
    ->find()
    ->where(function(QueryExpression $exp, Query $query) {
        return $exp->between(
            $query->newExpr(
                $query->connection()->driver()->quote(
                    '2014-03-31',
                    \PDO::PARAM_STR
                )
            ),
            new IdentifierExpression('start_date'),
            new IdentifierExpression('end_date')
        );
    });
对于CakePHP附带的所有SQL方言都支持的这样一个基本SQL表达式来说,这可能会感到有点不方便,因此您可能有理由在这里使用具有值bindig的原始SQL代码段

但是,应该注意的是,当涉及到例如跨方言支持时,表达式通常是更好的选择,因为它们可以(或多或少)在编译时轻松地进行转换,请参见
sqldialtartrait::\u expressionTranslators()
的实现。此外,表达式通常支持自动标识符引用

值绑定 通过手动值绑定,您几乎可以创建任何您喜欢的内容。然而,应该注意的是,只要有可能,您就应该使用表达式,因为它们更容易移植,这对于很多表达式来说已经是开箱即用了

$Query = $Table
    ->find()
    ->where([
        'start_date BETWEEN :start AND :end'
    ])
    ->bind(':start', '2014-01-01', 'date')
    ->bind(':end',   '2014-12-31', 'date');
这样,第二种情况也可以很容易地解决,例如:

$Query = $Table
    ->find()
    ->where([
        ':date BETWEEN start_date AND end_date'
    ])
    ->bind(':date', '2014-03-31', 'date');
两者的混合(最安全和最兼容的方法) 也可以将两者混合使用,即使用使用自定义绑定的表达式,如下所示:

use Cake\Database\Expression\IdentifierExpression;
use Cake\Database\Expression\QueryExpression;
use Cake\ORM\Query;

// ...

$Query = $Table
    ->find()
    ->where(function(QueryExpression $exp, Query $query) {
        return $exp->between(
            $query->newExpr(':date'),
            new IdentifierExpression('start_date'),
            new IdentifierExpression('end_date')
        );
    })
    ->bind(':date', '2014-03-31', 'date');
这样,您就可以使用可能的可移植表达式处理第二种情况,而不必担心手动引用/转义输入数据和标识符

使用数组语法进行常规比较 尽管如此,最终之间的与使用两个单独的简单条件一样:

$Query = $Table
    ->find()
    ->where([
        'start_date >=' => '2014-01-01',
        'start_date <=' => '2014-12-32',
    ]);
这将导致类似的查询

SELECT 
    *
FROM
    table_name
WHERE
    start_date BETWEEN '2014-01-01' AND '2014-12-31'
SELECT 
    *
FROM
    table_name
WHERE
    '2014-03-31' BETWEEN start_date AND end_date

自定义表达式类 另一个选项是生成适当SQL代码段的自定义类。这里有一个例子

列名应该包装到标识符表达式对象中,以便自动引用(如果启用了自动引用),键>值数组语法用于绑定值,其中数组键是实际值,数组值是数据类型

请注意,直接为列名传递用户输入是不安全的,因为它们不会被转义!使用白名单或类似文件,确保列名可以安全使用

值之间的字段 这将生成一个类似于上面的查询

字段之间的值 另一方面,这将导致类似的查询

SELECT 
    *
FROM
    table_name
WHERE
    start_date BETWEEN '2014-01-01' AND '2014-12-31'
SELECT 
    *
FROM
    table_name
WHERE
    '2014-03-31' BETWEEN start_date AND end_date
表达式类
您可以使用以下两种方法之一

方法1:

$start_date = '2014-01-01 00:00:00';
$end_date = '2014-12-31 23:59:59';
$query = $this->Table->find('all')
         ->where(function ($exp, $q) use($start_date,$end_date) {
             return $exp->between('start_date', $start_date, $end_date);
         });
$result = $query->toArray();
$start_date = '2014-01-01 00:00:00';
$end_date = '2014-12-31 23:59:59';
$query = $this->Table->find('all')
         ->where([
            'start_date BETWEEN :start AND :end'
         ])
         ->bind(':start', new \DateTime($start_date), 'datetime')
         ->bind(':end',   new \DateTime($end_date), 'datetime');
$result = $query->toArray();
方法2:

$start_date = '2014-01-01 00:00:00';
$end_date = '2014-12-31 23:59:59';
$query = $this->Table->find('all')
         ->where(function ($exp, $q) use($start_date,$end_date) {
             return $exp->between('start_date', $start_date, $end_date);
         });
$result = $query->toArray();
$start_date = '2014-01-01 00:00:00';
$end_date = '2014-12-31 23:59:59';
$query = $this->Table->find('all')
         ->where([
            'start_date BETWEEN :start AND :end'
         ])
         ->bind(':start', new \DateTime($start_date), 'datetime')
         ->bind(':end',   new \DateTime($end_date), 'datetime');
$result = $query->toArray();

大家好,请使用此查询获取基于值范围的数据

    $query = $this->Leads->find('all', 
array('conditions'=>array('postcode BETWEEN '.$postcodeFrom.' and'.$postcodeTo.''), 'recursive'=>-1));
                  debug($query);
                  print_r($query->toArray());

我就是这样使用它的

$this->Table->find()->where(['data_inicio BETWEEN '.'\''.$data_inicio.'\''.' AND .'\''.$data_final.'\''.' ']);

我想这不是问题的答案。这个问题是基于cakephp 2.5的,所以如何在cakephp 3中执行类似的操作:“条件”=>[“开始日期介于?和之间”=>[“2014-01-01”,“2014-12-32']],因为它是条件的一部分,这很重要,这样我们就可以在分页上编写它$this->Model->find('all',['conditions'=>$conditions])或$this->paginate=['conditions'=>$conditions]@JohnLaniba我不知道你想说什么。我的意思是,我有很多代码在分页时看起来像这样$this->paginate=['conditions'=>$conditions]$conditions是数组,它在cakephp 3上工作,除了中间条件。因此,如何在数组条件上执行类似的操作:'conditions'=>['start_date BETWEEN?AND?'=>['2014-01-01','2014-12-32']]有些奇怪,但下面的答案似乎是正确的。因此,正如这个“条件”=>[“开始日期介于“2014-01-01”和“2014-12-32”之间]@JohnLaniba我的答案中所示的技术是处理用户输入(必须被视为不安全)和/或稍后需要转换表达式(例如,自定义SQL方言)时应该使用的技术。如果您实际上已经硬编码了字符串值,那么构建一个简单的SQL代码段字符串也是一个可能的解决方案。也就是说,对于复杂条件,您可以将闭包传递给
conditions
选项,就像
where()
接受闭包一样,或者您可以自己构建查询并将其传递给分页器(它接受表和查询对象)。不,请不要使用此选项!这是一个SQL注入漏洞-您永远不应该信任用户数据并将其直接包含到查询中,这正是本示例所做的,因为条件中的单值项,就像
key=>value
项的左侧值一样,不受绑定,相反,这些字符串将按原样插入查询中!
$this->Table->find()->where(['data_inicio BETWEEN '.'\''.$data_inicio.'\''.' AND .'\''.$data_final.'\''.' ']);