First, every time you use mysqli_fetch_assoc
it will return the next result, ie the moment it does this:
while(mysqli_fetch_assoc($busca) != false){
array_push($rows,mysqli_fetch_assoc($busca));
}
You run two mysqli_fetch_assoc
for each loop, that is if your query is only bringing one result per loop of for($i = 0; $i < count($palavras_pesquisa) ; $i++){
so it will always merge NULL
another thing you compared with FALSE
in mysqli_fetch_assoc($busca) != false
, which does not make sense, because mysqli_fetch_assoc
returns or array
or null
only, also use mysqli_error
to detect errors.
The most correct thing to do:
$busca = mysqli_query($conn,"SELECT * FROM usuarios WHERE nome REGEXP '$string'") or die(mysqli_error($conn));
//'$busca' sempre retorna false, fazendo com que o restante abaixo não seja executado.
while ($dados = mysqli_fetch_assoc($busca)) {
array_push($rows, $dados);
}
In short, ALWAYS DO EXACTLY AS THEY ARE IN THE DOCUMENTATION EXAMPLES (usually adoc in English this is most correct in most cases), even if they are not great , yet yes it is better than wrong use, or randomly use without knowing what you are doing, the effect of mysqli_fetch_assoc
is similar to yeld
, for every time you use mysqli_fetch_assoc
it will bring the next line.
However making a SELECT
for each loop can be wasteful, you could simplify doing this:
for($i = 0; $i < count($palavras_pesquisa) ; $i++){
$string = '.*'.$palavras_pesquisa[$i].'*';
$busca = mysqli_query($conn,"SELECT * FROM usuarios WHERE nome REGEXP '$string'");
Prefer to use implode
and just do a query, thus:
<?php
session_start();
if(isset($_POST['pesquisa'])){
$palavras_pesquisa = explode(' ',$_POST['pesquisa']);
$conn = mysqli_connect('localhost','root','','secure_login');
$rows = array();
$ids = array();
if (!empty($palavras_pesquisa)) { //Verifica se tem palavras
foreach ($palavras_pesquisa as &$value) {
$value = '.*' . $value . '*';
}
$consulta = "nome REGEXP '" . implode("' OR nome REGEXP '", $palavras_pesquisa) . "'"; //Cria um OR pra cada palavra
$busca = mysqli_query($conn, "SELECT * FROM usuarios WHERE " . $consulta) or die(mysqli_error($conn));
while ($dados = mysqli_fetch_assoc($busca)) {
$rows[] = $dados;
}
}
for($i = 0;$i < count($rows); $i++){
...
Another thing, ALWAYS MAKE A GOOD INDENTING OF THE CODE , this helps not to get lost.
However it is also recommended not to pass data directly in the query, this is due to sqlinjection, if you are using mysqli then you would prefer to use prepared statement , it would look like this:
<?php
session_start();
if(isset($_POST['pesquisa'])){
$palavras_pesquisa = explode(' ', $_POST['pesquisa']);
$conn = mysqli_connect('localhost', 'root', '', 'secure_login');
$rows = array();
$ids = array();
if (!empty($palavras_pesquisa))//Verifica se tem palavras
{
//Gera where
$consulta = rtrim(str_repeat(''nome' REGEXP ? OR ', count($palavras_pesquisa)), 'OR ');
//Gera tipos parâmetros
$paramsTypes = str_repeat('s', count($palavras_pesquisa));
//Gera referencias
$params = array();
$params[] = &$paramsTypes;
foreach ($palavras_pesquisa as $value) {
$value = '.*' . $value . '*';
$params[] = &$value;
}
$stmt = mysqli_prepare($conn, "SELECT * FROM 'usuarios' WHERE " . $consulta);
//Adiciona o stmt como primeiro item no array
array_unshift($params, $stmt);
if ($stmt) {
//Passa array como parâmetros no bind_param
call_user_func_array('mysqli_stmt_bind_param', $params);
if(!mysqli_stmt_execute($stmt)) {
echo 'Erro no stmt:', mysqli_stmt_error($stmt);
exit;
}
$result = mysqli_stmt_get_result($stmt);
while ($dados = mysqli_fetch_assoc($result))
{
$rows[] = $dados;
}
mysqli_stmt_close($stmt);
} else {
echo 'Erro no prepare:', mysqli_error($conn);
exit;
}
}
for($i = 0;$i < count($rows); $i++){
...
See the documentation to understand the functions I used in the last example:
Mysqli:
Understand the criticisms here as suggestions for you to improve.