代码之家  ›  专栏  ›  技术社区  ›  dmive

laravel项目中的过滤foreach

  •  0
  • dmive  · 技术社区  · 9 年前

    目前,我正在为二手产品开发一个平台,我正在与laravel合作。

    我只想显示距离当前用户最多10公里的产品。 用户位置和产品位置存储在数据库中,我在将产品发送到视图的同一控制器中计算它们之间的距离。

    现在,我想知道我是否可以在这个控制器中计算出的距离上过滤我的foreach,这样我就可以过滤出距离超过10km的产品。

    我觉得我的代码不是很好,所以我愿意考虑其他的方法来实现这一点。

    控制器功能:

     public function getNearest()
        {
            $products= Product::orderBy('created_at','DESC')->paginate(5);
    
            foreach($products as $product) {
    
        //function that calculate distance
            $user = Auth::user();
            $address = $product->locatie;   //location of product
            $prepAddr = str_replace(' ','+',$address);
            $geocode=file_get_contents('https://maps.google.com/maps/api/geocode/json?address='.$prepAddr.'&sensor=false');
            $output= json_decode($geocode);
            $latitude = $output->results[0]->geometry->location->lat;
            $longitude = $output->results[0]->geometry->location->lng;
    
            $address2 = $user->locatie; //location current user
            $prepAddr2 = str_replace(' ','+',$address2);
            $geocode2=file_get_contents('https://maps.google.com/maps/api/geocode/json?address='.$prepAddr2.'&sensor=false');
            $output2= json_decode($geocode2);
            $latitude2 = $output2->results[0]->geometry->location->lat;
            $longitude2 = $output2->results[0]->geometry->location->lng;
    
    
            $coordinate1 = new Coordinate($latitude, $longitude); //location current user
            $coordinate2 = new Coordinate($latitude2, $longitude2); //location product
    
            $calculator = new Vincenty();
            $d = $calculator->getDistance($coordinate1, $coordinate2);
            $distance =$d/1000;
    
                    $product->distance = round($distance);
    
            if($product->distance>10){
               //dont show product above 10km and filter foreach somehow?
            }
            }
    
    
            return view('welcome',compact('products'));
        }
    

    查看:

    @foreach ($products as $product)
        <div class="col-lg-3 margin-tb">
            <img src="/uploads/products/{{ $product->afbeelding }}">
            <p>{{ $product->name}}</p>
            <p>{{ $product->details}}</p>
            <p>{{ $product->price}}</p>
             <p>{{ $product->locatie}}</p>
            <p>{{ $product->distance}} km van jouw locatie</p>
    
    
    
    
            <a href="/Zoekertjes/{{ $product->id }}">bekijken</a>
    
        </div>
        @endforeach
    
    1 回复  |  直到 9 年前
        1
  •  0
  •   Paras    9 年前

    不是最理想的解决方案,但它应该有效:

    public function getNearest()
        {
            $products= Product::orderBy('created_at','DESC')->paginate(5);
            $user = Auth::user();
            $address2 = $user->locatie; //location current user
            $prepAddr2 = str_replace(' ','+',$address2);
            $geocode2=file_get_contents('https://maps.google.com/maps/api/geocode/json?address='.$prepAddr2.'&sensor=false');
            $output2= json_decode($geocode2);
            $latitude2 = $output2->results[0]->geometry->location->lat;
            $longitude2 = $output2->results[0]->geometry->location->lng;
            $coordinate2 = new Coordinate($latitude2, $longitude2); //location user
    
            $products->reject(function($product, $key) use($coordinate2) {
    
        //function that calculate distance
    
            $address = $product->locatie;   //location of product
            $prepAddr = str_replace(' ','+',$address);
            $geocode=file_get_contents('https://maps.google.com/maps/api/geocode/json?address='.$prepAddr.'&sensor=false');
            $output= json_decode($geocode);
            $latitude = $output->results[0]->geometry->location->lat;
            $longitude = $output->results[0]->geometry->location->lng;
    
            $coordinate1 = new Coordinate($latitude, $longitude); 
            //location product
    
            $calculator = new Vincenty();
            $d = round($calculator->getDistance($coordinate1, $coordinate2) / 1000);
    
            return $d > 10;
            });
    
    
            return view('welcome',compact('products'));
        }
    

    我之所以说它不是最优的,是因为你不能保证收到5个结果(分页不起作用)。这是因为您在php级别而不是数据库级别具有距离逻辑。解决这一问题的一种方法是计算产品的数量,以及它们是否<5、获取更多结果并计算距离,如果它们>5,取前5。

    当然,最好的方法是在DB级别处理距离计算