You can use
LIKE
and
OR
in the query and
preg_split
(equivalent to
explode
, but you can isolate more spaces without needing to filter) in PHP to split the string:
if (isset($_POST['busca']{0})) { //Tem que ter digita ao menos uma letra
$buscas = preg_split('#\s+#', $_POST['busca']);
... aqui vai o código mysql, podendo usar a API PDO ou MSYQLI ...
}
If the form is POST use $_POST['busca']
, if not use $_GET['busca']
Note: If you are using UTF-8 please read this post: Doubt with charset = iso- 8859-1 and utf8
Using with MYSQLI
<?php
$mysqli = new mysqli('SERVIDOR', 'USUARIO', 'SENHA', 'BANCO');
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit;
}
if (isset($_POST['busca']{0})) {
$buscas = preg_split('#\s+#', $_POST['busca']);
$qtdPalavras = count($buscas);
//Gera os LIKEs
$where = str_repeat('nome LIKE ? OR ', $qtdPalavras);
$where = substr($where, 0, -4); // Remove o OR extra
$query = 'SELECT id, nome, data FROM livros WHERE ' . $where . ' ORDER BY nome LIMIT 100';
$stmt = $mysqli->prepare($query);
if ($stmt) {
//Adiciona os tipos de parâmetros
array_unshift($buscas, str_repeat('s', $qtdPalavras));
$qtdPalavras++;//Atualiza o total
for ($i = 0; $i < $qtdPalavras; $i++) {
//Evita adicionar o sinal de porcentagem no primeiro item, que são os tipos de parâmetros
if ($i > 0) {
//O sinal de porcentagem é necessário para busca em qualquer posição
$buscas[$i] = '%' . $buscas[$i] . '%';
}
//Passa o valor como referencia (& - E comercial), pois bind_param não aceita variáveis normais
$buscas[$i] = &$buscas[$i];
}
//Chava os valores da array como parametros
call_user_func_array(array($stmt, 'bind_param'), $buscas);
//Executa
$stmt->execute();
//Vá adicionando as colunas aqui que necessitar
$stmt->bind_result($id, $nome, $ano);
while ($stmt->fetch()) {
echo 'Nome:', $nome, '<br>';
echo 'Ano:', $ano, '<hr>';
}
$stmt->close();
} else {
die('Erro:' . $mysqli->error);
}
}
The query according to the search will generate in a POST like "O Acopolato Odisseu"
something like:
SELECT id, nome, ano FROM livros WHERE nome LIKE ? OR nome LIKE ? OR nome LIKE ? ORDER BY nome LIMIT 100
The queries get the values of bind_param
and the bank will execute something like:
SELECT id, nome, ano FROM livros WHERE nome LIKE '%O%' OR nome LIKE '%Acopolato%' OR nome LIKE '%Odisseu%' ORDER BY nome LIMIT 100
Using with PDO
If PDO should look something like this:
<?php
try {
$pdo = new PDO('mysql:host=SERVIDOR;dbname=BANCO', 'USUARIO', 'SENHA');
} catch (PDOException $e) {
die('Connection failed: ' . $e->getMessage());
}
if (isset($_POST['busca']{0})) {
$buscas = preg_split('#\s+#', $_POST['busca']);
$qtdPalavras = count($buscas);
//Gera os LIKEs
$where = str_repeat('nome LIKE ? OR ', $qtdPalavras);
$where = substr($where, 0, -4); // Remove o OR extra
$sth = $pdo->prepare('SELECT id, nome, data FROM livros WHERE ' . $where . ' ORDER BY nome LIMIT 100');
if ($sth) {
for ($i = 0; $i < $qtdPalavras; $i++) {
$buscas[$i] = '%' . $buscas[$i] . '%';
}
$response = $sth->execute($buscas);
if ($response) {
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
echo 'Nome:', $row['nome'], '<br>';
echo 'Ano:', $row['data'], '<hr>';
}
} else {
echo 'Erro: ';
var_dump($sth->errorInfo());
}
}
}