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 😉
egregio tutorial anche questo complimenti
Grazie mille voglio dare al blog uno stampo un pò più improntato al developing rispetto ad altri siti concorrenti!
Ciao,
lo script non è completo. Si potrebbe averlo completo. Grazie
hmmm allora mi impegnerò anche io per contribuire alla realizzazione di questo obbiettivo! >,<
=)
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?
così pronto no ma è un buon suggerimento per un prossimo articolo 😉
Complimenti per la spiegazione, ottimo tutorial.
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 🙂
Nessun consiglio?
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).
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
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
Ciao come si può adattare l’esempio con mysqli?