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 you don’t use $_GET['busca']
Note: if using UTF-8 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 as 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
Questions receive the values of bind_param
and the bank will run 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 it’s PDO it 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());
}
}
}
WHERE COLUMN LIKE '%O%' OR COLUMN LIKE '%Acopolato%' OR .......
– user60252
You will have to separate the words in PHP and make a query with BD criteria.
– Sam
Okay, I get it. But for that, every word has to be saved in a separate column in the comic book, right? But it’s not so...?
– Neevs
Using
LIKE '%palavra%'
locates the word at the beginning, middle or end of the column value. UsingLIKE 'palavra%'
locates only at the beginning andLIKE '%palavra'
locates only at the end. It is also possible to make combinations, for example find when you have two separate wordsLIKE '%palavra%outra%'
.– Laércio Lopes