Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

klawdyo

Erro com Classe mysql

Recommended Posts

Galera. Criei a classe abaixo. Muito simples, como vocês podem ver.

 

<?
class SQL
{
//Variável que guarda os dados da conexão
  private $conn;

/*
Conecta com o banco de dados
*/
  public function conecta()
  {
	$server = "localhost";
	$user = "root";
	$pass = "";

	$bd = "banco_teste";

	$this->conn = mysql_connect($server,$user,$pass);
	mysql_select_db($bd);

	return true;
  }

  public function executa($sql)
  {
	$this->conecta();
	return $resultado = mysql_query($sql);
	$this->desconecta();
  }

  public function consulta($sql)
  {
	$result = $this->executa($sql);
	return $linha = mysql_fetch_array($result);
  }

  public function apaga($tabela, $id)
  {
	$this->executa("delete from " . $tabela . " where id='" . $id . "'");
	return true;
	$this->desconecta();
  }

  public function desconecta()
  {
	mysql_close($this->conn);
  }
}
?>

Essa classe funciona perfeitamente, e tem me poupado várias linhas de código.

 

Acontece que, em busca da portabilidade, eu quero evitar chamar funções mysql dentro do código, pois, se eu precisar mudar de banco de dados, eu facilmente alteraria só a classe, ou melhor ainda, eu criaria várias classes, para vários bancos de dados diferentes, mas com nomes dos métodos padronizados, e que funcionassem de modo idêntico em todas elas.

 

Portanto, ao invés de usar a executa(), e chamá-la assim:

$db = new SQL;
	$result = $db->executa("select * from movimento");
while($linha = mysql_fetch_array($result))
  {
	 //códigossss
  }

Criei a função consulta() para ser usada assim, ou seja, direto no while:

$db = new SQL;
  while($linha = $db->consulta("select * from movimento"))
  {
	 //códigossss
  }

Se vocês observarem, lá dentro da classe, a função consulta() executa o código sql, joga dentro do mysql_fetch_array e me recorda o resultado do mysql_fetch_array, ou pelo menos, deveria me retornar.

 

Acontece que está dando um erro de loop infinito, ou seja, ele só me retorna o primeiro resultado, por exemplo, o resultado com ID=1, e fica repetindo até comer toda a memória.

 

Porque isso acontece?

Onde eu estou errando?

Como alterar, de forma que funcione como proposto?

 

Valeu

Compartilhar este post


Link para o post
Compartilhar em outros sites

Galera, A quem possa interessar.

Alterei a função consulta() para

 

public function consulta($sql)
  {
	 $result = $this->executa($sql);
	 while($linha = mysql_fetch_array($result))
	 {
		  $buf[] = $linha;
	 }
	 return $buf;
  }

Dessa forma, posso chamá-la assim, diretamente no código:

<?
  $db = new SQL;

  foreach($db->consulta("select * from movimento") as $lin)
  {
	 echo $lin['id'];
  }
?>

Não estou usando o while, mas o foreach. Dessa forma resolvi a mer** do loop infinito.

Bom, é isso.

Alguém poderia dar uma sugestão melhor?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom ja que pediu uma opniao se da pra melhorar eu gostaria de dar umas dicas

 

sempre use as tags completas

<?php

 

a sua função conecta retorna true, sem ao menos testar se a conexao teve sucesso.

você poderia colocar os dados de conexao num arquivo.php separado

você chama o metodo executa e dentro dele o metodo conecta, entao no seu caso o metodo conecta nao precisa ser public

você poderia usar construtores e destrutores

executa e consulta poderia ser uma função só no caso sendo "executa"

e você retorna sempre mysql_fetch_array, isso deixou o metodo engessado, pois nao tem como você retornar outros tipos sem mecher no codigo

 

você precisa melhorar as validações de retorno, e melhorar o jeito de usar a classe.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fabyo,

Anotei suas sugestões, e as implementarei assim que concluir os outros projetos em andamento.

 

Mas...e quanto à função consulta()?

public function consulta($sql)
  {
	 $result = $this->executa($sql);
	 while($linha = mysql_fetch_array($result))
	 {
		  $buf[] = $linha;
	 }
	 return $buf;
  }

Conforme eu já expliquei, eu quero que ela me retorne os bichos já prontos, pra eu chamar mais fácil e sem usar o mysql_fetch_array (ou outro) dentro do código. Exemplo:

<?
  $db = new SQL;

  foreach($db->consulta("select * from movimento") as $lin)
  {
	 echo $lin['id'];
  }
?>
O problema, que tá bem claro inclusive, é que eu tô sendo redundante no loop, ou seja, eu faço um while pra criar o array e depois uso em um foreach. Como fazer a função consulta me retornar um array igual como tá retornando agora, mas sem usar dois loops de uma vez?

É possível?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá, Fabyo. Acontece que não funciona. Se eu usar um while, entra num loop infinito. Se eu usar um foreach, ele só exibe o primeiro resultado várias vezes. Tiipo, se era pra retornar 3 resultados, ele só retorna o primeiro resultado.

 

Por exemplo, se eu fizer a função consulta assim:

 

public function consulta($sql)
	{
		$result = $this->executa($sql);
		return mysql_fetch_array($result);
	}

E depois chamá-la assim, só como teste:

$linha	= $db->consulta($sql);

	foreach($linha as $lin)
	{
		print_r($linha);
	}
Ele me retorna o primeiro resultado 14 vezes (Não sei porque 14 exatamente. Mas aqui sempre retorna 14 dessa forma)

 

Se eu chamar assim:

$linha	= $db->consulta($sql);

	foreach($linha as $lin)
	{
		print_r($lin);
	}
Ele me retorna só o primeiro resultado

 

Se eu chamar assim:

$linha	= $db->consulta($sql);
	while($linha)
	{
		print_r($linha);
	}
Ele fica repetindo o primeiro resultado infinitamente, até acabar a memória

 

 

E aí? Alguma sugestão? Onde eu estou errando?

Compartilhar este post


Link para o post
Compartilhar em outros sites

	public function consulta($sql)
{
	$result = $this->executa($sql);
	return mysql_fetch_array($result);
}
  $linha	= $db->consulta($sql);

print_r($linha);

foreach($linha as $lin)
{
	echo $lin."<br />";
}

 

testa ai

Compartilhar este post


Link para o post
Compartilhar em outros sites

hehehe

A mesma coisa... só retorna o primeiro resultado.

 

Já tô quase desistindo. E aí, mas alguma idéia?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Rapaz.. isso é um mistério.. porque você disse que tá funcionando normal, aí eu fui testar com php normal, pois estava testando com o PHP-GTK. Aí ficou da mesma forma. E eu usei do mesmo jeito que você disse.

 

Arquivo class.MYSQL.php

public function consulta($sql)
	{
		$result = $this->executa($sql);
		return mysql_fetch_array($result);
	}

Arquivo de teste

include_once("class.MYSQL.php");

	$db			= new SQL;
	
	$sql		= "select * from movimento";
	$linha		= $db->consulta($sql);

	print_r($linha);

	foreach($linha as $lin)
	{
		echo $lin."<br />";
	}

E o resultado foi esse assim, sem alterar uma vírgula:

Array ( [0] => 1 [id] => 1 [1] => Klawdyus [cliente] => Klawdyus [2] => 2008-03-27 03:06:00 [entrada] => 2008-03-27 03:06:00 [3] => 2008-03-27 04:06:00 [saida] => 2008-03-27 04:06:00 [4] => 1 [tipo] => 1 [5] => Pago [situacao] => Pago [6] => 1 [valor] => 1 ) 1
1
Klawdyus
Klawdyus
2008-03-27 03:06:00
2008-03-27 03:06:00
2008-03-27 04:06:00
2008-03-27 04:06:00
1
1
Pago
Pago
1
1

Compartilhar este post


Link para o post
Compartilhar em outros sites

faz do jeito que eu te falei só com 1 loop

 

  

public function consulta($sql)
 {
$this->conecta();
return mysql_query($sql);
 }

 

  $linha	= $db->consulta("select * from movimento");
while($l = mysql_fetch_array($linha))
{
	print_r($l);
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Essa daí ficaria igual à função executa() da mesma classe. Desse jeito funcionaria normal. Mas é que eu não quero usar nada relativo a "mysql" no código, apenas na classe específica, pra facilitar uma possível mudança de base de dados, entendeu? Eu quero criar outras classes padronizadas, de forma que eu possa mudar tudo apenas mudando o arquivo de classe.

É que esse sistema também poderá usar o sqlite, o firebird e até o access, dependendo de onde ele irá ser instalado. Essa será uma opção definida das configurações dele e vai variar de cliente pra cliente.

 

:(

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tava não

O executa era mais padrão, serviria pros inserts, deletes e updates também, enquanto o consulta era só pra select mesmo. Veja:

public function executa($sql)
  {
	$this->conecta();
	return $resultado = mysql_query($sql);
	$this->desconecta();
  }

  public function consulta($sql)
  {
	$result = $this->executa($sql);
	return $linha = mysql_fetch_array($result);
  }

Esse código tá lá em cima, no primeiro post, quando coloquei a classe inteira

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tô entendendo como você tá falando. E concordo com você.

Acontece que ele só tá sobrando pq tá errado.

 

Agora, deixe eu tentar te explicar a minha intenção com isso.

 

O executa faz só executar o mysql_query, então ela é mais genérica, e se eu fosse usá-la para fazer um select, eu precisaria incluir no código da minha página um while($lnha =mysql_fetch_array){}

 

Acontece que eu criei uma função chamada consulta exclusiva para fazer os selects, deixando a executa só pros inserts, deletes e updates. Essa função consulta deveria me retornar o conjunto de dados em forma de array, sem que eu chamasse mysql_fetch_array na página. Eu quero chamar mysql_fetch_array apenas na classe.

 

A questão é que eu só estou conseguindo esse resultado quando eu uso 2 loops, um na classe pra gerar esse array, e outro na página, pegando esse array e exibindo linha por linha, conforme o segundo post aqui desse tópico.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.