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 😉

0 0 voti
Valutazione dell'articolo
Iscriviti
Notificami
guest

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

15 Commenti
Vecchi
Più recenti Le più votate
the nerd corner
the nerd corner
14 anni fa

egregio tutorial anche questo complimenti

angelo
angelo
Rispondi a  Riccardo Mel
13 anni fa

Ciao,
lo script non è completo. Si potrebbe averlo completo. Grazie

Giacomo
Giacomo
14 anni fa

hmmm allora mi impegnerò anche io per contribuire alla realizzazione di questo obbiettivo! >,<

trackback
Raccolta di articoli della settimana 30/10/2011 | Saverio Gravagnola
14 anni fa

[…] un form di ricerca avanzata PHP/MYSQL (Target […]

Simone
Simone
14 anni fa

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?

Vinccenzo Palumbo
Vinccenzo Palumbo
14 anni fa

Complimenti per la spiegazione, ottimo tutorial.

Portapipe
Portapipe
14 anni fa

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 🙂

portapipe
portapipe
13 anni fa

Nessun consiglio?

Marco89
Marco89
13 anni fa

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

Gennaro
Gennaro
13 anni fa

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

migo80
migo80
12 anni fa

Ciao come si può adattare l’esempio con mysqli?

Rimani Aggiornato
Nuove idee, zero Spam
Ti invieremo solo le ultime novità di articoli o nostri progetti.
Iscrivendoti accetti la nostra privacy poliicy. Una volta iscritto, ricordati di attivare l'iscrizione cliccando sul link ricevuto via mail.
15
0
Esprimete la vostra opinione commentando.x