[RESOLVIDO] - Consulta trazendo resultados diferentes entre PHP e MySQL(PhpMydmin)

Olá Experts!

Criei a consulta:
$sql = "SELECT MAX(id),token,latitude,longitude,altitude,data_hora FROM device WHERE token=’$token’ ";

No PhpMydmin(MySQL) trás o resultado correto, que eu espero:
SELECT MAX(id),token,latitude,longitude,altitude,data_hora FROM device where token=‘SMO_010’

Já no PHP, quando faço consulta pelo Postman, me trás o ultimo registro e não o que selecionei:

Conseguem me dizer onde estou errando?

Como vc ta executando sua query no php?

Olá Rode!

Muito obrigado pelo seu apoio, ela esta assim, tentei das duas maneiras, com duas query’s que no banco trás o resultado esperado, mas no PHP não:

1a. Opção:

<?php
//Pegando o Token

$token = $_POST[‘token’];

//Importando banco de dados
require_once(‘connection.php’);
include ‘connection.php’;

//Criando o sql
$sql = "SELECT MAX(id),token,latitude,longitude,altitude,data_hora FROM device WHERE 
token='$token'";

//pegando resultado
$result = mysqli_query($con, $sql);

//recebendo o numero de linhas
$number_of_row = mysqli_num_rows($result);

if($number_of_row > 0){
while($row = mysqli_fetch_assoc($result)){
$temp_array[] = $row;
}//while
}//if

header('Content-Type: application/json');
   
//exibindo em formato json_decode
echo json_encode(array('device'=>$temp_array));
   
//fecha a conexao
mysqli_close($con);   

?>	

2a. Opção:

<?php
//Pegando o Token
$token = $_POST['token'];

//Importando banco de dados
require_once('connection.php');
include 'connection.php';


//Criando o sql
$sql = "SELECT id,token,latitude,longitude,altitude,data_hora FROM `device` WHERE 
token='$token' ORDER BY id DESC LIMIT 1";

//pegando resultado
$result = mysqli_query($con, $sql);

//recebendo o numero de linhas
$number_of_row = mysqli_num_rows($result);

if($number_of_row > 0){
while($row = mysqli_fetch_assoc($result)){
    $temp_array[] = $row;
}//while
}//if

header('Content-Type: application/json');

//exibindo em formato json_decode
echo json_encode(array('device'=>$temp_array));

//fecha a conexao
mysqli_close($con);


?>

Aparentemente tudo normal, coloque um apelido no MAX e um group by para garantir e ver o que retorna:

SELECT MAX(id) AS id,token,latitude,longitude,altitude,data_hora 
FROM device WHERE token='$token' 
GROUP BY token,latitude,longitude,altitude,data_hora

Não deu certo Rode, além de não trazer o ultimo, trás um range aletorio.

Ja tentou usar api PDO?

http://php.net/manual/pt_BR/book.pdo.php

Talvez pode ser um problema da api mysqli…

Rode!

É lógica desta função que esta incorreta, ele esta trazendo o ultimo array de objetos:
if($number_of_row > 0){
while($row = mysqli_fetch_assoc($result)){
$temp_array[] = $row;
}//while
}//if

Resultado:

Que é o ultimo registro da tabela:

Só não descobri uma lógica para resolver este caso, neste caso, o PHP teria que pegar este ultimo registro e decrementar até que localize o ultimo token.

Mas ai que está, não falei nada antes pra não confundir mas vamos la:

Quanto se usa funções de agrupamento (SUM, AVG, MAX, MIN, etc) sem usar group by, obrigatoriamente vc só trás um registro ok?

Logo, vc nem precisa do while pra pegar o registro…

$row = mysqli_fetch_assoc($result);
if ($row != null) {
    print_r($row);
} else {
    echo 'Sem registros na tabela!';
}

Sempre observe o retorno das funções que vc usa…

E para pesquisar, o banco usa um negócio chamado cursor e no php cada vez que usa o fetch_assoc vc pede mais um registro pro banco até chegar a nulo (null), ou seja, um indicador de que não tem mais registros a serem usados…

Agora analisando sua lógica, não deveria afetar em nada porque ele só entraria no while uma unica vez correto?

Eu ainda suspeito que possa ser bugs da api mysqli como um todo, estude um pouco de pdo, bem mais pratico (minha opinião) de mexer com banco, no seu caso olha o basico aqui:

$sql = 'SELECT MAX(id) AS id,token,latitude,longitude,altitude,data_hora FROM device WHERE token=?';

$pdo = new PDO('mysql:host=localhost;dbname=banco', 'usuario', 'senha');
$stmt = $pdo->prepare($sql);
$stmt->execute(array($token));
$temp_array = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($temp_array);

Bons estudos!

OBS: Código ajustado para quem tiver interesse…

Rode,
As primeiras tentativas de montar este WS foi com PDO, mas devido a pouca experiencia e aos erros acabei fazendo em mysqli.

Alterei para PDO mas trás nulo:
<?php
//Pegando o Token
$token = $_POST[‘token’];

   //Criando o sql
   //$sql = "SELECT id,token,latitude,longitude,altitude,data_hora FROM device WHERE token=? ORDER BY id DESC LIMIT 1";
       $sql = "SELECT MAX(id) AS id,token,latitude,longitude,altitude,data_hora FROM device WHERE token=?";
       
       //Importando banco de dados
       $pdo = new PDO('mysql:host=localhost;dbname=banco', 'usuario', 'senha');
       $stmt = $pdo->prepare($sql);

       if(!$stmt->execute(array($token))){
          echo '<pre> erro: ';
          print_r($stmt->errorInfo());
          exit;
       }//if

       $temp_array = $stmt->fetch(PDO::FETCH_ASSOC);
                
   
   header('Content-Type: application/json');
   
   //exibindo em formato json
   echo json_encode(array('device'=>$temp_array));
   
   //fecha a conexao  
       $conn = null;

?>

resultdo:

'mysql:host=localhost;dbname=banco', 'usuario', 'senha'

Você trocou os exemplos pelo seu banco, usuário e senha certo?

Coloca isso no topo do código pra debugar:

<?php
ini_set('display_errors', true);
error_reporting(E_ALL);
...

Alguma mensagem de erro?

Bom dia Rode!
Sim troquei, claro, só retirei o link de consulta e os dados de acesso por segurança…vou seguir sua recomendação é logo te falo.

Abraços e muito obrigado,

1 curtida

Aproveita e da uma checada no banco pra ver qual engine e qual charset (charset e collate) suas tabelas estão usando…

Já tive alguns problemas com PDO e MySQL por causa disso, principalmente com engine=InnoDB

Se seu código não aprensentar nenhum erro, depois acrescente isso apos sua senha…

...'senha', array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8") );

No exemplo está utf8 mas vc deve trocar pelo que seu banco está usando (ISO-8859-1, latin1, etc)

Mais informações de uma olhada:

Rode, boa tarde!

A engenee é InnoDB e arrumei os collations, procurei deixar padronizado com utf8_general_ci

Já o debug não rodou neste servidor, tentei também rodar no eclipse acho que falta algo para rodar o PDO no Eclipse(plugins), fica as marcações:

“PDO cannot be resolved to a type”

veja se o módulo pdo está instalado em sua máquina, pode tentar usando

<?php
phpinfo();

Abrindo a pagina ele mostra todos os módulos instalados… caso vc não encontre pdo e mysql_pdo (algo do tipo não me recordo ao certo), vc terá de instala-los e reiniciar seu servidor apache/nginx…

Se estiver usando linux (parabéns :joy:), basta digitar o comando no terminal para listar os módulos instalados…

php -m

Quanto ao collation apenas tome cuidado se já haviam dados com texto acentuado, vc terá de mudar todos na mão se antes era ISO-8859-1 por exemplo, caso o contrário verá tudo “grego” na base…

No eclipse tente usar uma contra-barra no pdo assim:

...new \PDO...

Rode,

Valiosas dicas:

Rs!!! Olha só a mensagem, informado que a variavel esta indefinada:

image

Setei direto no código com valor: “SMO_010” trouxe o resultado certinho:

Então quer dizer que o Postman não esta enviando o valor ou o PHP não esta recebendo/entendendo este valor.

Nunca usei postman, será que ele não estava mandando get?

Outra dica, para alguns casos, o seu acho que pode se aplicar… o php aceita tanto get quanto post usando request…

$token = $_REQUEST('token');

E uma forma de saber como a requisição chegou…

echo $_SERVER['REQUEST_METHOD'];

O contra-barra funcionou ou era falta de módulo?

Sucesso irmão, boa sorte!

Olá querido amigo Rode!

O contra barra no Eclipse não funcionou, lendo documentação fala para descomentar (que já esta descomentado) a tag no php.ini…mas depois com calma vou ver isso…

Já a requisição chegou como POST. Uma verificação mais sucinta no Postman, vi que eu estava colocando a variável em local errado, na verdade eu estava inserindo a variável no Headers e trocando para o Body o resultado apareceu:

Outra coisa que não tinha feito nos outros testes(não sei se isto também conta pelo erro que estava apresentado) já que na linha com dados de acesso PDO já contem s informações do banco, mas inseri as requisição de conexão:

//Requisitando a conexão com banco de dados
require_once(‘connection.php’);
include ‘connection.php’;

Post [RESOLVIDO] com sucesso!

1 curtida