【问题标题】:PDO wrong bindings with LaravelLaravel 的 PDO 错误绑定
【发布时间】:2014-12-31 18:49:09
【问题描述】:

我有一个完美的搜索查询(我删除了一些不重要的代码):

$posts = new Post;

if(Input::has('query')) {
    // Search for posts with title or tags matching the given criteria
    $posts = $posts
        ->addSelect(DB::raw("MATCH(posts.title) AGAINST (?) as post_score"))
        ->addSelect(DB::raw("MATCH(tags.title) AGAINST (?) as tag_score"))
        ->where(function($query) {
            return $query
                ->whereRaw('MATCH(posts.title) AGAINST (?)')
                ->orWhereRaw('MATCH(tags.title) AGAINST (?)');
        })
        ->orderBy(DB::raw('post_score+tag_score'), 'desc')
        ->setBindings([ $input['query'], $input['query'], $input['query'], $input['query'] ]);
}

但只要我在上述if() 语句之前添加这段代码:

if(Input::has('filter')) {
    $posts = $posts->whereType($input['filter']); //Filter type by either 'article' or 'question'
}

...我收到此错误:

[2014-11-04 19:28:18] production.ERROR: PDO error: SQLSTATE[HY093]: Invalid parameter number (SQL: select `posts`.*, COALESCE(SUM(post_votes.rating), 0) as rating, MATCH(posts.title) AGAINST (css) as post_score, MATCH(tags.title) AGAINST (css) as tag_score from `posts` left join `post_tags` on `post_tags`.`post_id` = `posts`.`id` left join `tags` on `tags`.`id` = `post_tags`.`tag_id` left join `post_votes` on `post_votes`.`post_id` = `posts`.`id` where `type` = css and (MATCH(posts.title) AGAINST (css) or MATCH(tags.title) AGAINST (?)) group by `posts`.`id` order by post_score+tag_score desc, `views` desc) [] []

我输入了css 作为搜索查询,该类型应在question 上进行过滤。如您所见,变量未正确绑定(不知道正确的词)。这怎么可能?我也试过这个不起作用:

->where(function($query) use ($input) {
    return $query
        ->whereRaw('MATCH(posts.title) AGAINST (?)', [$input['query']])
        ->orWhereRaw('MATCH(tags.title) AGAINST (?)', [$input['query']]);
})

提前致谢。

【问题讨论】:

    标签: mysql laravel pdo eloquent query-builder


    【解决方案1】:

    这是你需要的:

    if(Input::has('filter')) {
      $posts->whereType($input['filter']); //Filter type by either 'article' or 'question'
    }
    
    if(Input::has('query')) {
      // no need for this:
      // $posts = $posts
      // just:
      $posts
        ->addSelect(DB::raw("MATCH(posts.title) AGAINST (?) as post_score"))
        ->addBinding($input['query'], 'select')
        ->addSelect(DB::raw("MATCH(tags.title) AGAINST (?) as tag_score"))
        ->addBinding($input['query'], 'select')
        ->where(function($query) use ($input) {
           $query
             ->whereRaw('MATCH(posts.title) AGAINST (?)', [$input['query']])
             ->orWhereRaw('MATCH(tags.title) AGAINST (?)', [$input['query']]);
        })
        ->orderBy(DB::raw('post_score+tag_score'), 'desc')
    }
    

    【讨论】:

    • 谢谢,完美!唯一的事情是,我需要$posts = $posts->(...) 才能让它工作。只是$posts->(...) 不是为我做的。非常感谢。
    • @JasonK 你得到什么错误?我很肯定你不需要做$posts = $posts->...,因为你在 Builder 对象上操作。
    • 是的,你是对的,现在它确实有效。我只需要在开始时做$posts = $posts->select('posts.*')。如果我不这样做,搜索查询将无法正常工作(但没有错误)。
    • 没错,如果您仍然需要所有字段,那么您首先需要select
    • ->addSelect(DB::raw("MATCH(tags.title) AGAINST (?) as tag_score")) ->addBinding($input['query'], 'select') 等价于->selectRaw("MATCH(tags.title) AGAINST (?) as tag_score", $input['query'])
    猜你喜欢
    • 2013-02-14
    • 2013-10-24
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    • 2016-03-29
    • 2014-10-07
    • 2016-11-06
    • 2017-06-22
    相关资源
    最近更新 更多