简体   繁体   中英

How To Filter Product By Category in Laravel or PHP

im trying to filter products by categories for example look at this url http://127.0.0.1:8000/index?category=php,html,js the result it must the products that have php and html languages. these are my tables

Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('title',100);
    $table->text('description');
    $table->text('cover');
    $table->text('file');
    $table->integer('user_id');
    $table->integer('price');
    $table->timestamps();
});
Schema::create('languages', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->timestamps();
});
Schema::create('product_language', function (Blueprint $table) {
    $table->integer('product_id');
    $table->integer('technology_id');
});

产品模块

语言模块

PrTe 模块

IndexController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Product;
use App\Language;
use App\PrTe; //this is the pr_tes table module, which have (product and languages) Foreign Keys

class HomeController extends Controller
{
    public function index()
    {
        $Products = new PrTe;
        $Queries = [];
        $Columns = [
            'languages.title'            => 'category',
        ];
        $CategoryParameters = array_filter(explode(',',request('category')),function($value){
            return !is_null($value) && $value !== '';
        });
        $Products = $Products::join('products', 'pr_tes.product_id', '=', 'products.id')
                             ->join('languages', 'pr_tes.language_id', '=', 'languages.id');
                             
        foreach ($Columns as $Field => $Column) 
        {
            if(request()->has($Column) && request($Column) != null)
            {
                $Products = $Products->where($Field,request($Column));
                $Queries[$Column] = request($Column); 
            }
        }
        $Products = $Products->groupBy('products.id');
        $Products = $Products->paginate(5)->appends($Queries);
        return view('index',compact('Products'));
    }
}

*is this table design is good or not

First the relationship language should be languages since it is a hasMany.

The most Laravel way of doing this, is to use whereHas() . Something similar to this, instead of all the hoops your tried in your own solution. Utilizing when for only querying if categories are present.

$CategoryParameters = array_filter(explode(',', request('category')), function($value) {
    return !is_null($value) && $value !== '';
});

$products = Product::whereHas('languages', function ($query) use ($CategoryParameters) {
    $query->when(count($CategoryParameters), function ($query) use ($CategoryParameters) {
        $query->whereIn('title', $CategoryParameters);
    });
})->get();

The downside is whereHas() produces a not so fast exists SQL statement compared to the join solution. Since languages is programming languages, i do not believe performance will be a problem with this query any time soon. While the code being way more simple.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM