Wyszukiwarka php + html + mysql

0

Witam,
Proszę o pomoc. Napisałem korzystając z googla prosty sklep w php/laravel/mysql (w oparciu o phpMyAdmin). Wypisuje mi listę wszystkich produktów (książek) na ekran. Z uwagi że tych ksiazek może być z czasem sporo chciałbym dorobić wyszukiwarkę. W przeciwieństwie do php, sql dosyć umiem i można by tu wykorzystać składnie: WHERE LIKE %podany_wzorzec%. Tylko jak to przeklepać do php? Chyba że jest inny pomysł.

kod index.blade.php

 @extends('layouts.master')

@section('title')
    Mój Sklep
@endsection

@section('content')
    @if(Session::has('success'))
        <div class="row">
            <div class="col-sm-6 col-md-4 col-md-offset-4 col-sm-offset-3">
                <div id="charge-message" class="alert alert-success">
                    {{ Session::get('success') }}
                </div>
            </div>
        </div>
    @endif

    <form action="???.???"> //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ tu chciałem dać jakiegoś form'a by po submit mi generowało 
        Wyszukiwarka: <input type="text" name="fname">

        <input type="submit" value="Submit"><br><br> 
    </form>

    @foreach($products->chunk(3) as $productChunk)  //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  Wypis całej tabelki produktów na stronie
        <div class="row">
            @foreach($productChunk as $product)
                <div class="col-sm-6 col-md-4">
                    <div class="thumbnail">
                        <img src="{{ $product->imagePath }}" alt="..." class="img-responsive">
                        <div class="caption">
                            <h3>{{ $product->title }}</h3>
                            <p class="description">{{ $product->description }}</p>
                            <div class="clearfix">
                                <div class="pull-left price">${{ $product->price }}</div>
                                <a href="{{ route('product.addToCart', ['id' => $product->id]) }}"
                                   class="btn btn-primary pull-right" role="button">Dodaj</a>
                            </div>
                        </div>
                    </div>
                </div>
            @endforeach
        </div>
    @endforeach
@endsection

W załączniku przesyłam także screen wyglądu tabel i ich zawartość.

Moje pomysły:

  1. Poprzez formularz przesyłać i edytować to wyświetlanie. Tylko jak? Jak zmienić ten kod? Jestem zielony i nie mam pojęcia co gdzie i jak :((
  2. Poprzez formularz generować w SLQ stworzyc View albo jakąś dodatkową tabelkę zgodnie z frazą do wyszukania podanym przez użytkownika, następnie nie wyświetlać bazowej tabelki produktów tylko tą stworzoną na potrzeby wyszukiwania.
    C,d, Sql mogło by to byc tak:
 select *
into NowaTabelka
from Tabelka
where like '%fraza%';

Natomiast jak podłączyć się przez php do tego?

Rozwiązanie nie musi być piękne, byle działa. Słabe podejście domyślam się ale jest presja czasu projektu.
Jeżeli trzeba to z chęcią wstawię inne fragmenty kodu tylko proszę napisać jakie.

Pozdrawiam i proszę o pomoc

1

Umiesz dosyć dobrze SQL, ale o wyszukiwaniu pełnotekstowym nie słyszałeś? ;-)

1

Zobacz pod tym linkiem http://www.php.rk.edu.pl/w/p/pelnotekstowe-wyszukiwanie/
opisane jest to bardziej dokładnie tam.

1

Używasz Laravela i nawet do dokumentacji nie zajrzysz? https://www.laravel.com/docs/5.3/queries#where-clauses :(
a konkretniej masz w nim

$users = DB::table('users')
                ->where('name', 'like', 'T%')
                ->get();

ewentualnie ręcznie możesz coś naskrobać pisząc surowe zapytania:

use Illuminate\Support\Facades\DB;

$results = DB::select('select * from users where id = :id', ['id' => 1]);

To odnośnie LIKE, jednak jak zauważył @Patryk27 w tym przypadku lepiej sprawdzi się chyba wyszukiwanie pełnotekstowe i szukanie nie tylko po tytułach książek, ale również po autorach, wydawnictwach i co tam sobie jeszcze dodasz... :)

0

Dziękuję za wszelkie linki i porady. Czytałem dokumentacje i strony. Co stworzyłem:

  1. Na stronie index.blade.php wpisałem prosty formularz:
     <form action="{{ route('user.wyborRoute') }}" method="get">
        <font color="#f8f8ff">Wyszukiwarka:</font> <input type="text" name="fname">

        <button type="submit" class="btn btn-danger">OK</button>
        <br><br>
    </form>
  1. Formularz odnosi się do pliku routes.php
 Route::get('/wyborRoute', [    
    'uses' => 'ProductController@getIndexWyszukane', //getIndexWyszukane
    'as' => 'user.wyborRoute',
]);
  1. To odnosi się funkcją do: 'ProductController@getIndexWyszukane',
 public function getIndexWyszukane()
    {    
        $products = Product::all()->where('id', '<', 10); // id w tabelce są: 1,2,3,4,5,6,7,11,12... Dokładny obraz w załączniku post nr.1
        return view('shop.wyborRoute', ['products' => $products]); // testuje dla przykładu z słówkiem where aby wypisać id mniejsze od 10 czyli  prawie wszystkie bez dwóch (11,12).
    }
  1. Przekierowuje mnie to do shop.wyborRoute, które jest identyczne jak index.php, gdzie wypisuje mi całą tabelkę. Tam mam foreache:
 @foreach($products->chunk(3) as $productChunk)
        <div class="row">
            @foreach($productChunk as $product)
                <div class="col-sm-6 col-md-4">
                    <div class="thumbnail">
                        <img src="{{ $product->imagePath }}" alt="..." class="img-responsive">
                        <div class="caption">
                            <h3>{{ $product->title }}</h3>
                            <p class="description">{{ $product->description }}</p>
                            <div class="clearfix">
                                <div class="pull-left price">${{ $product->price }}</div>
                                <a href="{{ route('product.addToCart', ['id' => $product->id]) }}"
                                   class="btn btn-primary pull-right" role="button">Dodaj</a>
                            </div>
                        </div>
                    </div>
                </div>
            @endforeach
        </div>
    @endforeach
  1. Niestety nic nie wypisuje.

@@@@@ Przemyślenia @@@@@:
Co ciekawe:
$products = Product::all(); // to dziala wypisuje wszystkie
$products = Product::all()->where('id', '<', 10); // nie erroruje ale nic nie zwraca.... zatem złe polecenie?
Na stronie dokumentacji wiekszośc poleceń ma słówko get oraz DB::table

 $users = DB::table('users')->get();

U mnie jest to troszke inaczej skonfigurowane i używam **$products = Product::all() **

Screen Product.php

 <?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $fillable = ['imagePath', 'title', 'description', 'price'];
}

Składnia się różni na to wygląda, jak to poprawić?
Gdy już wipisze mi ID < 10 to trzeb będzie przesyłać argument z formularza do funkcji w Controlerze i tam podstawiać do where i powinno działać.

Dziękuję za wsparcie i ponownie prosze o pomoc.

0

Odkryłem że:

$products = Product::all()->where('title','Harry Potter');
return view('shop.wyborRoute', ['products' => $products]);

Zwraca i wypisuje na ekran wynik z książką harry potter, tak samo odnosi się to do id:

$products = Product::all()->where('id','1');
return view('shop.wyborRoute', ['products' => $products]);

Zwraca to samo. Składnia w dokumentacji jest inna. Na drugim miejscu jest '<' albo 'like'.
Cieszę się że coś się w końcu pojawiło. Ale nie mogę dać żadnej nie równości czy tez funkcji LIKE która zwróci mi nie jedną książkę tylko kilka.

Przesyłam załącznik z screenem funkcji

Proszę o pomoc

0

Działa pobieranie frazy z input() i wyszukuje ów obraza

     public function getIndexWyszukane(Request $request)
    {   $zmienna = 'SzukanaFraza';
        $zmienna = $request->input('suchen');
        echo "Wypisz szukaną ksiazke: $zmienna";
        $products = Product::all()->where('title',$zmienna);
        return view('shop.wyborRoute', ['products' => $products]);
    }

Na skrajne minimum mój kod spełnia oczekiwania, bo znajduje pojedyncza książkę po tytule, tytuły raczej się nie powtarzają.
Jednak wciąż szukam z tym LIKE bądź wyszukiwaniem Pełno kontekstowym. Nie rozumiem dlaczego składnia w dokumentacji różni się od tej działającej w moim kodzie.

Dziękuję za każdą pomoc, myślę że jestem na ostatniej prostej, tylko co wpisać w WHERE(key:string, value, bool) by zadziałało

1

Jak słusznie zauważyłeś, większość przykładów ma na końcu słówko get. Skoro już wspominamy o dokumentacji to https://www.laravel.com/docs/5.3/queries#retrieving-results i tam jest wyraźnie napisane:

"The table method returns a fluent query builder instance for the given table, allowing you to chain more constraints onto the query and then finally get the results using the get method."

Tak więc używając query buildera piszesz sobie zapytanie, dodajesz warunki, dodajesz joiny itd. i dopiero po wywołaniu metody get() na końcu tak na prawdę zapytanie jest wykonywane. Metoda get() zwraca nam całą kolekcję obiektów. Możesz również zwrócić pierwszy element używając zamiast niej metody first().
all() używasz tylko bezpośrednio na Product ,żeby zwrócić całą tabelę z bazy, co przy dużych zbiorach jest mało wydajne i w zależności od tego co chcesz zrobić powinieneś użyć odpowiednich, innych metod.

Dlatego jeżeli chcesz w jakiś sposób wyfiltrować tabelę to nie ma sensu poprzedzać wherów all(), powinieneś dodać najpierw ograniczenia i zależnie od tego jaką informację potrzebujesz wyciągnąć używasz odpowiedniej metody (get(), first(), value(), pluck(), max(), avg() itd... po więcej ponownie odsyłam do dokumentacji).

Twoje zapytania powinny wyglądać mniej więcej tak, żeby działały:

$products = Product::where('id', '<', 10)->get();
$product = Product::where('title','Harry Potter')->first();

No i Twoja 'konfiguracja' $products = Product::all() nie jest konfiguracją, tylko lekkim błędem w zrozumieniu tego wszystkiego, ponieważ jak wspomniałem to nie robi nic więcej jak zwraca cała tabele z bazy.

Dodatkowo jeżeli wyciągasz coś po id to możesz użyć metody find()
czyli książkę o id = 1 wyciągasz:

$product = Product::find(1);
0

@Doggye: Z chęcią przetestuję twoją składnię, dziękuję także za wyjaśnienie. Ogólnie komendy z dokumentacji nie działały w moim kodzie, co mnie dziwiło.
Pisałem także na Stacku i tam podano mi wczoraj rozwiązanie:

 Product::where('title', $variable) ->orWhere('title', 'like', '%' . $variable . '%')->get();

Dziękuję wszystkim za pomoc, temat zamknięty :)
Pozdrawiam

0

Może PHP Sphinx?

1 użytkowników online, w tym zalogowanych: 0, gości: 1