Realizzare un form di ricerca avanzata PHP/MYSQL

Dopo la versione “semplice” del form di ricerca in php/mysql vi sottopongo anche questa versione più avanzata, ma molto più precisa e professionale.

01 Precisazioni importanti prima di partire

Il form di ricerca avanzata che sto per proporvi si basa sull’indice FULLTEXT, prima di partire però servono alcune, doverose, precisazioni:

– Questo tipo di ricerca è MOLTO più precisa e selettiva rispetto al semplice LIKE “%$variabile%” in quanto si basa anche sulla corrispondenza esatta in percentuale (scarta tutti i risultati con incidenza <5/10%).

– Funziona solo con tabelle myISAM (NO mysql vecchiotti), i campi della tabella devono contenere indici fulltext (vedremo dopo come inserirli).

– Vi è un limite nei campi, in quento il metodo analizza solo campi di tipo TEXT, VARCHAR et simila (NO INT DATE etc).

– Una cosa che non viene spiegata da tutti, ma che è molto importante (ci ho sbattuto la testa un pomeriggio), è che la tabella deve contenere ALMENO 3 record. Questo perchè altrimenti l’incidenza sarebbe pressochè uguale per tutti, e di default MYSQL taglia i risultati (altrimenti dovrebbe visualizzarli tutti). Mi è capitato infatti nelle prime prove di aver inserito solo 2 record di prova e il sistema non visualizzava nulla. Guardando la doc per fortuna ho capito XD

02. Come faccio a inserire gli indici fulltext?

Come anticipato prima per un corretto funzionamento abbiamo bisogno di indici fulltext, ovvero dobbiamo dire molto banalmente alla tabella quali saranno i campi per la ricerca da tenere indicizzati. Per aggiungere gli indici a tabella già esistente eseguiamo questa query da terminale sql:

ALTER TABLE tabella ADD FULLTEXT(titolo, testo,campo3);

Non vi preoccupate, a prima vista non è cambiato nulla. Potete anche aggiungere gli indici in modo visuale per chi è meno esperto, cliccando sull’iconcina T nel vostro pannello phpmyadmin vicino ad ogni campo della vostra tabella.

03. Ora che ho gli indici cosa me ne faccio?

Possiamo facilmente creare il nostro, potente, motore di ricerca usando PHP. Creiamo un form di ricerca a 3 campi: nome, cognome e residenza. Dopodichè creiamo il motore di ricerca vero e proprio:

File: engine-search-avanzato.php

//recupero i valori via post dal precendete form di ricerca
$nome = $_POST['nome'];
$cognome = $_POST['cognome'];
$residenza = $_POST['residenza'];

//inizio il loop
require_once("connessione_db.php");  //connessione db

mysql_select_db("$db_name",$connessione); 

//query
$risultato = mysql_query("SELECT * FROM tabella WHERE MATCH ( nome, cognome, residenza) AGAINST ('$nome, $cognome, $residenza')");

//in caso di errore
			if (!$risultato) {

					exit ('<p> Errore mentre recuperavo i dati' . mysql_error() . '</p>');
			}

while ($row = mysql_fetch_array($risultato))   

		{

//stampo risultati a video come siete abituati

In termini molto pratici, la query indica:

“Seleziona dalla tabellax quando trovi una correlazione tra i valori cercati con i campi fulltext impostati prima (nome, cognome, residenza)” dopodichè stampiamo il loop sullo schermo con il ciclo while per visualizzare i risultati.

Provatelo, recupererà i valori dal vostro db con correlazione pressochè unica.

03. Versione ancora più selettiva

Ovviamente esistono molti usi e versioni a seconda delle esigenze particolari di ognuno (certi usano cicli if concatenati prima di associare le variabili per eliminare eventuali campi vuoti e rendere la ricerca ancora più precisa).

Supponiamo ad esempio di voler mostrare i valori recuperati in ordine di score (risultato) discendente. La query mysql cambierà così:

//verisone più avanzata
$risultato = mysql_query("SELECT *, MATCH(nome, cognome, residenza) AGAINST('$nome, $cognome, $residenza') as score
		FROM tua_tabella
		WHERE MATCH(nome, cognome, residenza) AGAINST('$nome, $cognome, $residenza')
		ORDER BY score DESC");

Il funzionamento e la sintassi è pressochè uguale a prima, però in questo caso vi è “score” ovvero il risultato della query che viene messo in ordine discendente. In questo modo il form visualizzerà prima i record trovati con percentuale di corrispondenza più elevata.

04. Voglio qualcosa di ancora più selettivo

Per i più smanettoni ed esperti vi è la possibilità di usare anche particolari operatori BOOLEANI per rendere le ricerche ancora più precise. La sintassi rimane sempre la medesima mostrata in questo articolo, ma possiamo ad esempio specificare la priorità di una variabile cercata rispetto ad un’altra (operatore >), oppure escluderne alcune (verrà usata solo nel caso non vi siano risultati utili con le altre variabili, operatore -$variabile_cercata).

Spero sia utile 😉

  1. Complimenti per il tutorial, ti scrivo per una piccola informazione o suggerimento su un nuovo articolo 🙂

    Hai un modo o un metodo per creare una ricerca avanzata su n tabelle?

  2. Ciao. Potresti mostrarmi un esempio del punto 4?
    Ho un sito con questo sistema di ricerca, classico per una ricerca in base a pertinenza e percentuale score, solo che ora vorrei vedere nelle prime posizioni quelli che hanno aggiornato il profilo di recente E in base alla pertinenza/score.

    Esempio: uno ha score maggiore o uguale al mio e viene visualizzato prima di me MA ho appena aggiornato il mio profilo oppure ho pagato ad esempio 1 euro per essere in testa a tutti.

    C’è modo o devo buttarmi su qualche classe preimpostata? Avendo già tutto pronto magari si tratta di una modifica minima.
    Grazie 🙂

  3. Innanzitutto scusa del ritardo (vorrei rispondervi sempre subito ma ho sempre mille cose da fare e mi dimentico). Hai cercato su google qualche tutorial (quelli inglesi perchè di ita c’è ben poco ben fatto) riguardo gli operatori booleani per la ricerca? Io partirei da lì anche perchè per realizzare un algortimo di ricerca “su misura” devi andare nell’avanzato. Se poi non trovi niente posso pensare a fare un articolo ma di sicuro più avanti (non ti prometto niente di pronto a breve).

  4. Ciao ho seguito la tua guida, ho creato il cerca.php contenente il codice


    <?php
    //recupero i valori via post dal precendete form di ricerca
    $nome = $_POST['nome'];
    //$cognome = $_POST['cognome'];
    //$residenza = $_POST['residenza'];

    //inizio il loop

    //connessione db
    require_once("include/connect.php");

    // richiamo il file di configurazione
    require 'include/config.php';

    mysql_select_db("$db_name",$connessione);

    //query
    $risultato = mysql_query("SELECT * FROM utenti WHERE MATCH (nome) AGAINST ('$nome')");

    //in caso di errore
    if (!$risultato) {

    exit (' Errore mentre recuperavo i dati' . mysql_error() . '');
    }

    while ($row = mysql_fetch_array($risultato))

    {

    //stampo risultati a video come siete abituati

    //Tabellazione

    echo '

    Nome

    ';

    while ($row = mysql_fetch_assoc($result)) {
    $nome = htmlentities($row['nome']);

    //$contratto = $contratto_arr[$row['contratto']];

    echo "
    $nome
    ";
    }

    echo '';

    // libero la memoria di PHP occupata dai record estratti con la SELECT
    mysql_free_result($result);

    ?>

    e lo richiamo con il seguente form

    ma niente mi da sempre errore sai dirmi dove sbaglio??
    Grazie in anticipo

  5. Ciao, innanzitutto complimenti per la guida.

    Io ho però un problema, ottengo sempre il messaggio di errore in output. In pratica io lavoro su un pc su cui è installato “avis web server”, il php e il mysql. Ho una tabella che si chiama “macelleria” ed ho creato un indice fulltext per uno dei 5 campi della stessa (per il campo “marca”). Il codice php che utilizzo è il seguente (ovviamente ho omesso la parte di accesso al database che so per certo che funziona ):

    if(!isset($_GET[‘cat’])){$cat=’0′;}else{$cat=$_GET[‘cat’];};
    if(!isset($_GET[‘string’])){$string=’0′;}else{$string=$_GET[‘string’];};

    echo $cat.’ ___ ‘.$string;

    $risultati =mysql_query(“SELECT * FROM $cat WHERE MATCH (marca) AGAINST (‘$string’)”);

    if (!$risultato) {

    exit (‘ Errore mentre recuperavo i dati’ . mysql_error() . ”);
    }

    $num=mysql_numrows($risultati);
    echo $num;
    ?>

    <?php echo '’.$cat.’ ‘; ?>

    Marca
    Descrizione
    Misura
    Note
    Img
    Add

    <?php
    $i=0;
    while ($i

    <?php echo ' ‘; ?>

    Grazie anticipatamente per l’aiuto

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.

Up Next:

Icone tags in psd per Wordpress

Icone tags in psd per Wordpress