MYSQLI_FETCH_ARRAY() expects parameter 1 [RESOLVIDO]

A msg abaixo está aparecendo e eu não consigo resolver.

Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in C:\wamp64\www\tarefa\form-edita.php on line 15 Call Stack

form-edita.php

<?php   include("cabecalho.php"); 
        include("conecta.php");
        include("banco-tarefa.php");


$id = filter_input(INPUT_POST, 'id');
$con = buscaTarefa($conexao, $id)
?>


<form class="criar-tarefa" enctype="multipart/form-data" action="" method="post">
    <h1>Editar tarefa</h1>
    <table class="table table-striped table-bordered">
        <?php while($dado = mysqli_fetch_array($con)){?>
        <tr>
            <td>Nome</td>
            <td><input class="form-control" type="text" name="nome" value="<?php echo $dado['nome'];?>" ></td>
        </tr>
        <tr>
            <td>Descriçao</td>
            <td><textarea class="form-control" name="descricao" ><?php echo $dado['descricao']; ?></textarea></td>
        </tr>
        <tr>
            <td>Codigo</td>
            <td><input class="form-control" type="number" name="codigo" value="<?php echo $dado['codigo'];?>" ></td>  
        </tr>
        <tr>
            <td>Anexo</td>
            <input type="hidden" name="MAX_FILE_SIZE" value="99999999"/>
            <td><input class="form-control-file" name="arquivo" type="file" ></td>
        </tr>
        <?php } ?>
    </table>
    <form action="edita-tarefa.php" method="post"> 
        <input type="hidden" name="id" value="<?=$dado['id']?>">
        <button class="btn btn-info">Salvar</button>
    </form>
</form>

<?php include("rodape.php"); ?>
function buscaTarefa ($conexao,$id){
        $query = "select * from tarefa where id = {$id}";
        return mysqli_query($conexao,$query);
    }

Essa linha falta um ponto-virgula no final…

$con = buscaTarefa($conexao, $id)

Após a correção, só para testes, coloque logo abaixo…

var_dump($con);
?>

Se imprimir resource, então está tudo certo, pois o erro que está dando é que o mysqli_query não está devolvendo um resource, mas sim um booleano (true/false) informando que sua query pode não estar correta, mas primeiro corrija o ponto-virgula pra ter certeza… aproveito para deixar algumas boas práticas

Se seu id for do tipo int/integer incula no seu filtro um validador…

$id = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT);

Assim o valor já vem convertido, e caso haja tentativa de invasão, retornará false/null (não me recordo as regras, vide documentação no site)…

No seu while, pode usar uma sintaxe alternativa, melhorando a leitura do códgo assim…

<?php while ($dado = mysqli_fetch_array($con)): ?>
...
<?php endwhile; ?>

Principalmente o fechamento, bem melhor que

<?php } ?>

Hoje você só está usando um recurso, mas e se tivesse um if/ else dentro desse while olha como ficaria…

    <?php } ?>
<?php } ?>

Ai ja viu a confusão, melhor não vacilar, a chance de erro é grande nesses casos… da mesma forma que o while tem seu endwhile, for tem seu endfor, if/endif, etc…

@rodevops obrigado pelas dicas.

Retorno:

C:\wamp64\www\tarefa\form-edita.php:8:boolean false

A query estaria errada ?

Provavelmente, você precisa usar mysqli_error() para identificar o erro…

echo mysqli_error($conexao);

De preferencia logo abaixo do $con = …

Verifique se não errou o nome da tabela ou campo/coluna…

Informou erro de sintaxe.

Você tem um erro na sua sintaxe SQL; verifique o manual que corresponde à sua versão do servidor MySQL para a sintaxe certa usar próximo ‘’ na linha 1

Use um echo na função para imprimir sua query e veja onde errou…

E volto a perguntar, você não errou o nome da tabela ou coluna, realmente se chamam tarefa e id?

$sql = ...;
echo $sql;

No seu caso, como seu sql é pequeno não vale a pena deixar o {} envolta de $id, apesar de que isso não deveria dar problemas na sua query, geralmente ele é usado (e necessário) em instruções mais elaboradas como…

"... where id = {$obj->id}"

Ou

"... where id = {$obj->getId()}"

Mas como disse antes, não deveria ter problemas para você…

Outra possibilidade é seu $id não retornar um número… bom seria usar um echo nele também…

@rodevops

Quando eu deixo assim:

$id = filter_input(INPUT_POST, ‘id’, FILTER_VALIDATE_INT);

ele retorna:

selecione * da tarefa em que id =

se eu deixo assim:

$id = filter_input(INPUT_POST, ‘id’);

retorna:

select * from tarefa where id = 0000000019

Sabe me dizer porque?




Mas logo depois eu achei o erro (pelo menos funcionou quando troquei)

<form action="" method="post"> 
        <input type="hidden" name="id" value="<?=$dado['id']?>">
        <button class="btn btn-info">Salvar</button>
</form>

E retirei $dado['id'] para $id :

<form action="" method="post"> 
        <input type="hidden" name="id" value="<?=$id?>">
        <button class="btn btn-info">Salvar</button>
</form>

E funcionou…

Na computação, 19 é inteiro, 0000000019 é texto representando um numero, nesse caso, você pode trocar o filtro por isso…

$id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);

Agora se na base você está salvando id com zeros na frente, é sinal que a coluna não é int, mas sim varchar ou char acertei?

Se sim não é muito recomendavel usar campos textos para representar chaves primárias na tabela, mas enfim… faça seus ajustes

Outro caso bem comum para representar numeros em texto é um cep, por exemplo…

01234567

Sem o zero na frente daria erro para achar a rua correta, ja que um cep deve obrigatoriamente conter 8 digitos, por isso ele continua sendo do tipo texto/string mas representando um número, logo se você converter para inteiro pode ocasionar erros pois um zero na frente representa outra forma (octal ou base 8) mas não vem ao caso pra você explicar isso no momento…

Conforme imagem em anexo, a coluna id é int(10) mas estava como ZEROFILL;

obs: não sabia o que ele fazia, mas descobri que preenche os espaços com 0

@rodevops
Cara muito obrigado pela ajuda que me deu, estudei PHP em 7 dias para poder fazer uma aplicação teste para um estágio.
Muito muito obrigado.

Bom ver alguém esforçado no fórum, o que mais se ve aqui ultimamente são “oportunantes” querendo tudo de mão beijada…

Agora vamos melhorar um pouco seu código? Posso lhe dar algumas sugestões?

Na função buscaTarefa, ela sempre irá retornar 1 único cadastro para edição correto? Nesse caso vocẽ já poderia retornar um registro ao invés do result para depois usar o fetch_assoc…

function buscaTarefa ($conexao,$id){
    $query = "select * from tarefa where id = {$id}";
    $result = mysqli_query($conexao,$query);
    return mysqli_fetch_object($result); // retorna um objeto...
}

Depois na hora de chamar…

//$con = buscaTarefa($conexao, $id);
$tarefa = buscaTarefa($conexao, $id);

 # validação...
if (!is_object($tarefa)) {
    die('Cadastro não encontrado!'); # nem exibe o formulário...
}
?>

E para popular (preencher) o formulário nem precisa de while (afinal você não vai percorrer vários registros)…

 ....
<input class="form-control" type="text" name="nome" value="<?=$tarefa->nome?>" >
...

Outra coisa, porque um formulário dentro do outro? Isso é totalmente desnecessário, o form interno você pode simplesmente remove-lo e mudar o action para primeiro…

<form class="criar-tarefa" enctype="multipart/form-data" action="edita-tarefa.php" method="post">
    ...
    <input type="hidden" name="id" value="<?=$tarefa->id?>">
    <button class="btn btn-info">Salvar</button>
</form>

Se esse form não tiver campo de arquivo/anexo para ser enviado, sugiro retirar o enctype, assim evita informar ao servidor que você vai enviar um arquivo sem nunca enviá-lo percebe?

O fato de você ter trocado $dado[‘id’] por $id não afetaria em nada se o cadastro viesse da base corretamente, por isso coloquei $tarefa->id que nesse caso dará no mesmo…

Além do mais, seu formulário acabaria enviando apenas o id para edita-tarefa.php, os outros campos nunca iriam chegar la por pertencerem ao formulário “pai” pegou?

Tenha em mente que um formulário serve como uma folha de papel com os dados e um destinatário, igual uma carta, se você possui dois formulários como pretende enviar os dois ao mesmo tempo para destinatarios diferentes?

Ou mehor ainda, imagine um form como uma caixa de papelão e os campos como itens guardados nessa caixa, quando se envia (submit) para um destinário (action) através do de um serviço (method) podendo ser sedex (post) ou pac (get) o pacote é selado e vai para entrega :joy: e todos aqueles itens serão entregues para uma única pessoa (servidor) :joy:

Bons estudos e bemvindo ao mundo php!

@rodevops
Nossa ficou bem melhor agora!

só mais uma coisa, está dando o erro.

Aviso: mysqli_fetch_object () espera que o parâmetro 1 seja mysqli_result, booleano dado em C: \ wamp64 \ www \ task \ banco-tarefa.php na linha 28

function buscaTarefa ($conexao,$id){
        $query = "select * from tarefa where id = {$id}";
        $result = mysqli_query($conexao,$query);
        //mysqli_fetch_object - > Retorna a linha atual do conjunto de resultados (objeto)
        return mysqli_fetch_object($result);
    }

De qualquer forma, muito obrigado…

Espero que eu consiga entrar nesse mundo da programação.

Sera o id novamente?

Sempre observe na documentação da função o que ela retorna, no caso do mysqli_query, caso a sql não esteja correta, retornará um booleano false ao invés do resource lembra?

Você retirou o FILTER_SANITIZE_NUMBER_INT?

Eu acabei mostrando a função e nem lembrei como você deixou o sql, minha intenção era só mostrar o retorno dela… mas acho que você pegou o jeito, agora é com você, inclusive identificar e ler os erros é muito importante para resolver os problemas (não tem jeito, inglês é necessário)

Boa sorte!

@rodevops

Cara, realmente muito obrigado por tudo!

1 curtida