Ir ao conteúdo
  • Cadastre-se

PHP SELECT dentro do FOREACH retorna só a última string da array mas quero todos


Posts recomendados

OLÁ A TODOS, Boa tarde. Preciso de ajuda com o seguinte script.

 

eu tenho uma array que é a seguinte:

 

array (size=7)
  0 => string 'gu' (length=2)
  1 => string 'tr' (length=2)
  2 => string 'fr' (length=2)
  3 => string 'ip' (length=2)
  4 => string 'al' (length=2)
  5 => string 'po' (length=2)
  6 => string 'xa' (length=2)


Cada string de duas da array letra é a abreviatura de uma cidade; eu quero fazer uma pesquisa na base da dados para cada sigla dessa para ver qual a cidade correspondente. Como vai ser necessariamente um resultado apenas, eu tive que usar o foreach.

 

Tipo

foreach($array as $variavel);
        {
        $busca = $conn->query("SELECT * FROM tabela WHERE sigla = '$variavel'");
        $resultado = $busca->fetch_assoc();
        echo ' - '. $resultado['significado_da_sigla'];

        }
}


Não está funcionando perfeitamente, porque imprime apenas o último resultado. A impressão que dá é que está processando tudo, mas na hora de mostrar o resultado, mostra só o do último. como o resultado posterior estivesse substituindo o anterior.

 

Por isso eu já tentei uma variável para ir acumulando o resultado, tipo

 

if (empty('$resultado_busca')) {
    $resultado_busca = $resultado['significado_da_sigla'];
    }
    else {
    $resultado_busca = $resultado_busca . ' - ' . $resultado['significado_da_sigla'];
    }

ou seja, se a variável $resultado_busca foi vazia (da primeira vez), então vai criar uma variável com esse nome e com o primeiro resultado, se a variável já existir (das outras vezes), então a variável vai ser igual à variavel anteriormente criado adicionando um traço e o próximo resultado.

 

E depois, em vez de imprimir a variável do fetch_assoc $resultado['significado_da_sigla'] eu imprimiria a variável &resultado_busca, que em cada ciclo iria acumulando os resultados. No entanto, essa estratégia também não está funcionando, essa não imprime nada na tela.

 

Alguém pode dar uma ajuda?

 

OBRIGADO, DESDE JÁ

Link para o comentário
Compartilhar em outros sites

  • Moderador

@juriscode

Tem uma coisa que não entendi na sua lógica aí.

 

Seu objetivo é trazer dados do banco de dados.  Mas você tá passando um array já preenchido e iterando este array, e fazendo uma busca na tabela a partir deste array. De onde vem os dados?

 

Como está modelado seu banco de dados?

O ideal é que você tenha uma tabela para as siglas e outra tabela para as cidades, ambas em um relacionamento de 1:N

 

Dito isso, não precisa do array.

 

Se você tiver esta estrutura:

tabela siglas

ID  sigla 
1    RS
2    SC
3    SP

tabela cidades

ID Cidade          ID_sigla
1  Porto Alegre    1
2  Rio Grande      1
3  Caxias do Sul   1
4  Abelardo Luz    2
5  Arroio Trinta   2
6  Aurora          2
7  São Paulo       3
8  Guarulhos       3
9  Campinas        3

O que temos aqui é que a tabela cidades terá um campo de chave estrangeira onde o ID é referente a sigla.

 

Com isso pode-se  fazer uma consulta única retornando todas as cidades de todas as siglas.

Caso queira uma cidade ou todas cidades de uma sigla específica você coloca na consulta.

 

A consulta geralmente fica fora do laço de foreach.

 

De qualquer forma...  Como está a sua tabela no banco de dados?

 

 

Link para o comentário
Compartilhar em outros sites

@DiF é quase isso. Na verdade é uma tabela de itinerários. com as siglas das cidades desse itinerário.


Tem uma célula de uma tabela dos itinerários com a linha completa, por exemplo, de Guaíra-PR até Londrina-PR.
gu tr fr ip al pe xa um cr tu cm pb eb fl ma sa mr mg ar rl ca lo (isso tudo dentro de uma mesma célula, tem que ser assim por causa da busca de itinerário)
E cada sigla significa uma cidade

gu - Guaíra
tr - Terra Roxa
fr - Francisco Alves
ip - Iporã
al - Altônia
po - Pérola
xa - Xambrê
um - Umuarama
cr - Cruzeiro do Oeste 
tu - Tuneiras do Oeste
cm - Campo Mourão
pb - Peabiru
eb - Engenheiro Beltrão
fl - Floresta
ma - Maringá
sa - Sarandi
mr - Marialva
mg - Mandaguari
ar - Arapontas
rl - Rolândia
ca - Cambé 
lo - Londrina

nesse caso, eu selecionei a cidade de origem e a cidade de destino daí por meio de um scrip eu retiro dessa célula com o itinerário completo apenas o que me interessa, que é da origem até o destino e transformo esse bloco de siglas em uma array. No caso do exemplo eu peguei de Guaíra até Xambrê.

 

gu tr fr ip al po xa um cr tu cm pb eb fl ma sa mr mg ar rl ca lo
gu tr fr ip al po xa ----------------------------------------------------------

Poderia pegar a partir de umuarama até maringá, de iporã até campo mourão, enfim, ele vai sempre pegar apenas as cidades do itinerário escolhido conforme cidade de origem e cidade de destino escolhidas.

 

Essa parte do script até transformar em array está funcionando perfeitamente. pega de toda a linha apenas as siglas referentes às cidades do itinerário escolhido. Eu tive que usar siglas porque na hora de fazer a busca pelo melhor itinerário, a melhor linha, no caso, tem que usar o like '$origme%$destino', números não trabalhariam direito com isso.

 

o problema é que eu tenho que transformar essas abreviaturas dos nomes das cidades em nome de cidades. por isso eu tente um foreach para cada string da array e um select sem while, porque é um resultado só para cada sigla.

obrigado pela ajuda, mas eu qeuro saber por que raios esse script está retornando apenas o significado da última string da array, não está acumulando os nomes das cidades do itinerário.

Link para o comentário
Compartilhar em outros sites

  • Moderador

@juriscode

Segundo seu array no primeiro post parece ser um array bidimencional. Nesse caso você teria que fazer pelo menos dois laços... mas não sei bem se realmente é isso. Isso pode ser a causa que você não consegue trazer outros dados

 

Mas ainda assim, acredito que seu banco de dados está extremamente mal modelado. Foi você quem fez ou isso é algo pronto de uma empresa de transporte?

 

No banco de dados, não se usa um mesmo campo para diversos tipos de informações.

Como eu mencionei anteriormente, o ideal é você separar as informações por tabelas. Mesmo que seja um itinerário.

Por exemplo:

Tabela de cidades(contém o nome completo da cidade)

Tabela de siglas (contém todas as siglas )

Tabela de rotas (aqui você inclui as rotas, ID da cidade, ID da sigla) Esta tabela seria N:N entre cidade e siglas.

 

Do jeito que suas tabelas estão, é capaz de gerar inconsistências. Por isso a importância da 1NF e 2NF na modelagem de banco de dados.

 

Um banco modelado de forma errada, poderá não trazer os dados de forma precisa.

 

Link para o comentário
Compartilhar em outros sites

É exatamente isso que eu fiz, mas Imagina que eu não te falei nada, começando do zero:


O fato é que eu tenho um array bidimensional com as siglas das cidades. array("gu","tr","fr","ip","al","po","xa")

 

Quero pegar essa array e fazer uma consulta no banco de dados para cada string e escrever na tela qual a cidade correspondente.


a minha tabela de dados é assim, além de outras cidades

SG | CIDADE
----------------------
gu | Guaíra
tr | Terra Roxa
fr | Francisco Alves
ip | Iporã
al | Altônia
po | Pérola
xa | Xambrê

 

  1. daí eu quero fazer uma consulta no banco de dados para cada sigla, retornando a cidade respectiva e escrevendo todas as cidades da array separadas por espaço, hífen, espaço.

 

Como fazer isso?

 

Link para o comentário
Compartilhar em outros sites

  • Moderador

@juriscode Vamos lá.

 

Um array é descrito desta forma:

$vetor = array("dado1","dado2","dado3");

 

Um array bidimensional seria algo assim:

 

$vetor = array("dado1"=>"valor-dado1",
               "dado2"=>"valor-dado2",
               "dado3"=>"valor-dado3");

Para iterar esse vetor fazemos assim:

foreach($arr as $item=>$key):
  echo "$item - $key </br>";
endforeach;

 

 

Um array multidimensional é descrito assim:

$vetor = array("dado1"=>array("dado1","dado2"),
               "dado2"=>array("dado3","dado4"), 
               "dado3"=>array("dado5","dado6"));

Para iterar o vetor simples podemos usar o laço de for ou foreach. 

Creio que o foreach é mais indicado para iterar vetores. 

foreach($vetor as $dados):
   echo "$dados <br/>";
endforeach;

Agora, quando temos um vetor multidimensional, é necessário fazer duas vezes o laço de iteração. Porque primeiro percorre o vetor, ele encontra cada elemento com mais um vetor.

Então é por isso que tem que fazer duas vezes:

foreach($vetor as $dados => $dados_array):
    foreach($dados_array as $data => $user_data): 
        echo "O elemento: $dados, contém $data com $user_data. </br> </br>";
    endforeach;
endforeach;

O retorno  do foreach simples seria:

dado1
dado2
dado3

Já o retorno do foreach duplo:

O elemento: dado1, contém 0 com dado1. 

O elemento: dado1, contém 1 com dado2. 

O elemento: dado2, contém 0 com dado3. 

O elemento: dado2, contém 1 com dado4. 

O elemento: dado3, contém 0 com dado5. 

O elemento: dado3, contém 1 com dado6. 

 

Ainda sobre o array multidimensional, tem uma função no php que reduz o código que é chamada de array_walk_recursive()

Com uma única função, você faz o papel de foreach duplo para iterar dois vetores.

 

array_walk_recursive($vetor, function ($item, $key) {
	echo  "O elemento: $key, contém $item. </br> </br>" ;	   
});

Retorno:

O elemento: 0, contém dado1. 

O elemento: 1, contém dado2. 

O elemento: 0, contém dado3. 

O elemento: 1, contém dado4. 

O elemento: 0, contém dado5. 

O elemento: 1, contém dado6. 

 

4 horas atrás, juriscode disse:

O fato é que eu tenho um array bidimensional com as siglas das cidades. array("gu","tr","fr","ip","al","po","xa")

Na verdade você tem aí um array simples.

 

Isso tudo só foi uma breve explicação de como lidar com os vetores.

O que na verdade você quer é puxar os dados do banco de dados.

Foi aí que eu perguntei antes, de onde vinha os dados que compõe o vetor? Do banco de dados(provavelmente)

 

Então o que você precisa é ter o BD bem modelado com as tabelas em relacionamento correto.

 

Tabela SG

ID  SG  IDcidade
1   gu     1
2   tr     2
3   fr     3
4   ip     4
5   al     5
6   po     6
7   xa     7 

Tabela cidade

ID cidade
1  Guaíra
2  Terra Roxa
3  Francisco Alves
4  Iporã
5  Altônia
6  Pérola
7  Xambrê

Repare que na tabela SG contém um campo chamado IDcidade.

Este campo é a chave estrangeira que recebe o valor ID da chave primária da tabela cidade.

Para fazer o relacionamento correto, é preciso criar um índice(index) na tabela SG para o campo IDcidade. No phpmyadmin é fácil adicionar um índice na tabela e selecionar o tipo "index" para o campo escolhido.

 

Bem voltando.

Com isso, feito, terá um relacionamento de 1:N, pois caso queira adicionar mais cidades para cada sigla, pode.

Para fazer a consulta e formatar do jeito que você quer:

4 horas atrás, juriscode disse:

separadas por espaço, hífen, espaço.

 

A consulta ao banco de dados será:

SELECT SG.SG, cidade.cidade FROM SG
INNER JOIN cidade ON cidade.ID = SG.IDcidade

 

Sabendo a query, no php você faz a consulta e insere dos dados em um laço de while.

$consulta = mysqli_query($conexao, "SELECT SG.SG, 
                                           cidade.cidade 
                                    FROM SG
                                    INNER JOIN cidade ON cidade.ID = SG.IDcidade");

while($itinerario = mysqli_fetch_object($consulta)):
    echo "$itinerario->SG - $itinerario->cidade";
endwhile;

Vai retornar:

gu - Guaíra 
tr - Terra Roxa 
fr - Francisco Alves 
ip - Iporã 
al - Altônia 
po - Pérola 
xa - Xambrê 

Onde o "gu" é o valor de SG.SG  e  "Guaíra" é o valor de cidade.cidade  OBS: nome-da-tabela.nome-do-campo 

No php as variáveis respectivas são: $itinerario->SG   e $itinerario->cidade

 

A forma que eu coloquei com o ->  é por causa da função mysqli_fetch_object()  que trata os dados como objetos e não como vetores.

 

Se quiser fazer com vetores aí a função é mysqli_fetch_array()  e as variáveis seriam $itinerario["SG"]  e $itinerario["cidade"]

Particularmente acho melhor e mais elegante o jeito com o object.

Ainda mais como no seu exemplo anterior que usou a função $conn->query()

 

Link para o comentário
Compartilhar em outros sites

  • Moderador

@juriscode Como eu disse anteriormente,  você não usa o array.  Não tem sentido. 

Se pelo que você disse, você popula o seu "array" com dados vindo de um banco de dados, porque não fazer as consultas necessárias direto?

 

Eu dei ali um exemplo de trazer todos os dados, mas você pode limitar isso dizendo o que exatamente você quer.

Ademais, lembre que eu disse que tudo depende de como você modela o banco de dados?

 

Se você quer mostrar uma rota, você precisa criar uma tabela de rotas.. 

ID  SG_pontoA   pontoA   SG_pontoB pontoB  
1       1          1         3        3
2       4          4         7        7

Onde os campos pontoA  e pontoB são chaves estrangeiras da outras tabelas.

Claro que aí, no caso você não vai mais pesquisar pela tabela SG, mas sim pela tabela de rotas

 

Aí você pode criar um itinerário de rotas do tipo:

 

Ponto A  gu - Guaíra   -   Ponto B fr - Francisco Alves

 

Pode ir até além disso e guardar até as posições de coordenadas de latitude e longitude e aí montar uma rota pelo google maps.  

 

PS: ali acima eu dei um exemplo só, não precisa ser exatamente assim. 

Ainda você não me explicou porque razão, você está criando um array.

 

 

 

Link para o comentário
Compartilhar em outros sites

Eu estou buscando resposta em outros foruns também e eu vou ter que chegar em casa para testar as sugestões

O problema é que toda a array está em um único campo do banco de dados. Isso não foi falha na modelagem de dados, mas necessário para fazer a busca de forma direta. E mesmo assim, a array não é todo o conteúdo da célula, mas apenas o trecho que interessa.

Mas, de qualquer forma, até por uma questão de flexibilidade (caso eu inclua mais rotas) eu preciso, necessariamente, pesquisar as strings da array, uma por vez e acumular o resultado.

Vou tentar com o fetchall, acumular o resultado na própria pesquisa e outras dicas, o que funcionar eu posto aqui.

 

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...