搜索插件Cakephp 3中的Concat字段

搜索插件Cakephp 3中的Concat字段,php,cakephp,cakephp-3.0,Php,Cakephp,Cakephp 3.0,目前,我正在实现friendsofcake搜索插件(版本1.2.3)。一切都按其应有的方式运行,但我希望包含以下两个字段: $this->searchManager() ->add('id', 'Search.Value') ->add('q', 'Search.Like', [ 'before' => true, 'after' => true, 'fi

目前,我正在实现friendsofcake搜索插件(版本1.2.3)。一切都按其应有的方式运行,但我希望包含以下两个字段:

    $this->searchManager()
        ->add('id', 'Search.Value')
        ->add('q', 'Search.Like', [
            'before' => true,
            'after' => true,
            'field' => [$this->aliasField('username'), $this->aliasField('name')]
        ])
        ->add('q', 'Search.Callback', [
            'callback' => function ($query, $args, $manager) {
               return $query->select(['name' => $query->func()->concat(
                    ['first_name' => 'identifier', ' ' , 'last_name' => 'identifier']
                )]);
            }
        ]);

因为我的数据库表分别存储first_name和last_name,所以我希望搜索插件搜索这两个字段的组合(名称)。上面的代码忽略了like子句,当我在回调中打印查询时,它似乎忽略了like操作。有人知道我如何在这个搜索插件中搜索两个字段吗?

你不能添加多个同名过滤器(
q
),后者将覆盖前者,它们不会合并

您还必须在回调中自己构建条件,即为
username
name
添加条件。此外,如果要使用
SELECT
子句中的聚合列进行匹配,或者也必须在
WHERE
条件中构建聚合列,则必须使用
HAVING
,这取决于所使用的DBMS,
WHERE
可能更快(虽然在使用像这样的
时可能不是这样,这使得不可能使用索引,即每一行都会被触碰)

下面是一个使用
have
的基本示例:

'callback' => function ($query, $args, $manager) {
    return $query
        ->select([
            $this->aliasField('username'),
            'name' => $query->func()->concat([
                'first_name' => 'identifier',
                ' ' ,
                'last_name' => 'identifier'
            ])
        ])
        ->having([
            'OR' => [
                $this->aliasField('username') . ' LIKE' => '%' . $args['q'] . '%',
                'name LIKE' => '%' . $args['q'] . '%'
            ]
        ]);
}

*未测试的示例

您不能添加具有相同名称的多个筛选器(
q
),后者将覆盖前者,它们不会合并

您还必须在回调中自己构建条件,即为
username
name
添加条件。如果要使用
SELECT
子句中的聚合列进行匹配,您还必须使用
HAVING
,或者您必须在
WHERE
条件-dep中构建聚合列以您正在使用的DBMS结尾,
其中
可能会更快(但在像
这样使用
时可能不会,这使得使用索引变得不可能,即每一行都会被触碰)

下面是一个使用
have
的基本示例:

'callback' => function ($query, $args, $manager) {
    return $query
        ->select([
            $this->aliasField('username'),
            'name' => $query->func()->concat([
                'first_name' => 'identifier',
                ' ' ,
                'last_name' => 'identifier'
            ])
        ])
        ->having([
            'OR' => [
                $this->aliasField('username') . ' LIKE' => '%' . $args['q'] . '%',
                'name LIKE' => '%' . $args['q'] . '%'
            ]
        ]);
}

*未测试示例

由于数据实际上是插入到结果中的,因此此解决方案对于SQL注入不安全,对吗?@markvdlaan93不确定您的意思,数据单独设置为
key=>值集中的值
,因此它是安全的,因为在条件下,右侧的值将被转义为unles它们是表达式对象(确切地说,这些值将在准备好的查询中设置为绑定参数)。@markvdlaan93您可以通过调试
$query->sql()
进行检查,它将显示占位符,当然您可以通过尝试插入一些内容来测试:),因为数据实际上是插入到结果中的,此解决方案对于SQL注入不安全,对吗?@markvdlaan93不确定您的意思,数据单独设置为
key=>value set
中的值,因此它是安全的,因为在条件下,除非它们是表达式对象,否则右侧值将被转义(确切地说,这些值将被设置为准备好的查询中的绑定参数)。@markvdlaan93您可以通过调试
$query->sql()
进行检查,它将显示占位符,当然您可以通过尝试插入某些内容来测试:)