【问题标题】:Laravel | Unable to get array of strings searched from the database拉拉维尔 |无法获取从数据库中搜索到的字符串数组
【发布时间】:2020-12-18 18:54:54
【问题描述】:

最终的用例是什么?

我的移动应用将发送https://example.com/public/api/classifiedsearch?search=name%3Aorange+apples+grapes+onions的查询

& 我希望结果包含来自products 表的数据,其中name 包含上面搜索字符串中的术语。我面临的问题是,我根本没有得到任何匹配的结果。我已经通过打印确认$terms(如下所述)确实能够将搜索中的值作为数组捕获,并且for循环的工作次数等于搜索字符串中的单词数。但没有返回任何结果。关于为什么不映射的任何提示/建议????

这是我在APIcontroller 中为classifiedsearch 所做的事情

public function index(Request $request)
{
    try{
       $queryString = $request->input('search',null);
         $terms = explode(" ",$queryString);
    
    // print_r($terms);
              
      if ( !empty( $request->query('search')))
      {
                   
        $products = Product::whereHas('store', function ($query) use ($terms) 
               {
                    foreach ($terms as $term) 
                    {
                     //    print_r("CHECKING FOR $term");
                    $query->where('name', 'like', '%' . $term . '%');
                    
                    }
               })->get();
          
      }
            
      else 
      {       
           $products = $this->productRepository->all(); 
      }
           
    } catch (RepositoryException $e) {
        return $this->sendError($e->getMessage());
    }

    return $this->sendResponse($products->toArray(), 'Products retrieved successfully');
}

输出:

{"success":true,"data":[],"message":"Products retrieved successfully"}

有人可以帮忙吗??

【问题讨论】:

    标签: php sql laravel laravel-5


    【解决方案1】:

    我知道你想达到什么目标,你可以试试这个:

    public function index(Request $request)
    {
      try{
        $queryString = $request->input('search',null);
        $terms = explode(" ", $queryString);
                
        if(!empty($request->query('search'))){       
          $products = Product::whereHas('store', function ($query) use ($terms){
            foreach ($terms as $key => $term){
              //if first loop, use Where, if multiple then add orWhere to current query
              if($key == 0)
                $query = $query->where('name', 'like', "%{$term}%");
              else
                $query = $query->orWhere('name', 'like', "%{$term}%");
            }
            return $query;
          })->get();
        }else{       
           $products = $this->productRepository->all(); 
        } 
      }catch(RepositoryException $e){
        return $this->sendError($e->getMessage());
      }
      return $this->sendResponse($products->toArray(), 'Products retrieved successfully');
    }
    

    【讨论】:

    • 你是从哪里来的人???!!!这正是我所需要的,它就像魔法一样工作。就我的用例而言,即使是我一直依赖的易受攻击的解决方案也确实有一些回扣。你今天让一个团队开心!!!!是的,这是我一直在思考的问题的解决方案!!!!其他发布答案的人并没有费心去完全理解最终的用例……非常感谢先生!干杯
    • 不客气@AdrianKarr,我来自地球哈哈哈
    【解决方案2】:

    代码中的问题是 search 参数的前缀是值 'name:' [在 HTML %3A 中解码为冒号:]

    search=name%3A橙子+苹果+葡萄+洋葱

    所以这一行:$terms = explode(" ",$queryString);

    实际上会返回一个数组:

    ['name:orange', 'apples', 'grapes', 'onions']

    由于您对术语的查询使用隐式 AND 来表示术语:

    $query->where

    它可能永远不会返回结果,因为它不太可能在数据库中具有以“name:”为前缀的值。

    我建议从前端客户端代码中的 GET 查询字符串中删除“name%3”。

    (另外,您可能想考虑将其作为术语的 OR 查询?所以它匹配任何名称,而不是强制匹配所有名称?您可以使用 $query->orWhere


    更新

    像这样尝试:

    $queryString = $request->input('search',null);
    $terms = explode(' ', $queryString);
    
    $products = Product::whereIn('name', $terms)->get();
    
    return $this->sendResponse($products->toArray(), 'Products retrieved successfully');
    

    【讨论】:

    • 按照说明删除名称:%3A 到搜索= 分隔...没有产生任何结果。我认为我获得 $product 的方式有问题?有什么不对吗?
    • @AdrianKarr 您是否尝试过使用:$query->orWhere,因为您现在使用的是 AND 搜索,这意味着所有关键字必须匹配。如果使用 orWhere(),则只需匹配一个。
    • 感谢您的提问和建议。我按照另一位绅士的建议尝试过,但并没有真正解决我的问题。我终于通过使用stackoverflow.com/a/63664380/13687099 解决了这个问题
    • 你所拥有的解决方案容易受到 SQL INJECTION 的攻击,你永远不应该包含这样的用户输入。
    • 感谢西里尔的帮助!真的很感激这个
    【解决方案3】:

    没有得到太多帮助并自己解决了这个问题。致未来可能需要的人:

    $condition = '';
       $terms = explode(" ",$queryString);
       foreach($terms as $text)  
          {  
               $condition .= "name LIKE '%".($text)."%' OR ";  
          }  
          $condition = substr($condition, 0, -4); 
          $sql_query = "SELECT * FROM products WHERE " . $condition; 
          $result = DB::select($sql_query);
    
    • condition 将收集所有要搜索的条件。
    • terms 将收集来自 URL 的所有搜索
    • 文本是数组中的单个项目。
    • products 是表的名称。
    • 使用数据库;如果您在不同的命名空间中,则应初始化。

    【讨论】:

    • 读到这里的人不应该使用这段代码,它很容易受到 SQL INJECTION 的攻击
    猜你喜欢
    • 1970-01-01
    • 2019-02-21
    • 2021-12-22
    • 2020-09-02
    • 2016-09-20
    • 2017-04-20
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多