Objota O mundo orientado a objetos

PHP – Problema com caracteres na conexão com o banco de dados utilizando PDO

Posted on setembro 13, 2012

Posted by Pedro

Olá galera, fica aqui uma dica bacana para quem está tendo problemas com caracteres na conexão com o banco de dados utilizando PDO.

Problemas com charset geralmente ocorrem quando você processa os dados no seu site em um formato X e no banco em um formato diferente. Ai começam os problemas. Um exemplo simples é o uso de ISO-8859-1 na codificação do seu site e um banco de dados configurado para trabalhar com charset UTF-8.

Nesse exemplo vou configurar parâmetros de conexão como o banco de dados MySQL já que é geralmente o mais utilizando com PHP, e trabalhar com  os dados no formato UTF-8.


//Exemplo da classe em PHP com extends na classe PDO. Aqui vamos atribuir todas as variáveis da nossa conexão pra trabalhar no formato UTF-8.

class MysqlConnection extends PDO {

public function Connection($dsn, $username = "", $password = "", $driverOptions = array()) {

parent::__construct ( $dsn, $username, $password, $driverOptions );

$this->exec("SET NAMES utf8");

$this->exec("SET character_set='utf8'");

$this->exec("SET collation_connection='utf8_general_ci'");

$this->exec("SET character_set_connection='utf8'");

$this->exec("SET character_set_client='utf8'");

$this->exec("SET character_set_results='utf8'");

}

}


//Aqui é a string de conexão / $dsn que vamos usar para conectar ao nosso banco

$dsn = "mysql:host=localhost;dbname=meu_banco_de_dados;charset=utf8";

Bom é isso. Muito simples, certo?

Qualquer dúvida pode postar um comentário que irei responder.

Até a próxima.

Usando classe de conexão com PDO – (exemplos práticos)

Posted on novembro 1, 2010

Posted by Rodrigo Ireno

Este artigo é uma complementação para o artigo anterior sobre PDO. Neste artigo viso ressaltar alguns detalhes não abordados anteriormente e utilizar de exemplos práticos.

Como mencionado no artigo anterior o uso do pdo facilitou muito mudar de banco de dados, porém isso não irá te livrar de uma diferença na sintaxe dos seus comandos SQL. Isso mesmo! Nem tudo é um mar de rosas com PDO.  Digamos que ele é um grande avanço para o php - afinal o Java já fazia uso deste tipo de estrutura. E como OOP agora é a bola da vez vemos pouco a pouco a transformação do php.

Outra coisa a mencionar é que não abordei como instalar o PDO, pois as atuais distribuições do php já vêm com PDO habilitado. Uma dica para os que quiserem saber quais drivers estão disponíveis para o seu servidor:

É comum não termos acesso ao php.ini de nossa hospedagem então, este é um modo de ver os drivers que estão habilitados na hospedagem que contratamos.


foreach(PDO::getAvailableDrivers() as $driver){
    echo $driver.'<br />';
}

Mas agora vamos ao que interessa, neste artigo vamos utilizar uma tabela no banco de dados Mysql para fazer algumas operações com ela utilizando pdo. Não será abordado como iniciar, pois outros artigos neste blog já descrevem este processo.

Nota: Sendo a única coisa a ressaltar de diferente do artigo anterior sobre PDO é que utilizei um array com argumentos no construtor:

array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)

Pois estes permitem que erros sejam capturados como exceções por um bloco try/catch. Veja mais detalhes na documentação

Utilize este comando SQL para criar nosso banco e tabela clientes de exemplo ou crie manualmente.


CREATE DATABASE `objota` ;

CREATE TABLE `objota`.`clientes` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`nome` VARCHAR( 255 ) NOT NULL ,
`telefone` VARCHAR( 100 ) NOT NULL ,
`email` VARCHAR( 100 ) NOT NULL
) ENGINE = MYISAM ;

A primeira coisa que vamos fazer é inserir dados no banco. Abaixo um exemplo de inserção utilizando a classe PDO:


try{
    //executa as instruções SQL
    $oConexao->exec("INSERT INTO clientes (nome,telefone,email) VALUES ('Rodrigo', '11-333-555', 'rodrigo@objota.com.br')");
    $oConexao->exec("INSERT INTO clientes (nome,telefone,email) VALUES ('Marcos', '55-555-888', 'marcos@mm.com.br')");
    $oConexao->exec("INSERT INTO clientes (nome,telefone,email) VALUES ('Maria', '11-888-9999', 'maria@maria.com.br')");
}catch (PDOException $e){
        //se houver exceção, exibe
        echo $e->getMessage();
}

Como vemos utilizamos o método exec para executar comando SQL no banco de dados. Neste caso inserimos três registros.

Agora veremos como consultar utilizando os recursos da classe PDO:


try{
    //executa uma instrução de consulta
    $result = $oConexao->query("SELECT * FROM clientes");
    if($result){
          //percorre os resultados via o laço foreach
           foreach($result as $item){
                  //exibe o resultado
                  echo "Nome: ".$item['nome'] . " - " . $item['telefone'] . $item['email'] ."<br>\n";
           }
    }
}catch (PDOException $e){
        echo $e->getMessage();
}

Como vimos para executar uma consulta utilizamos a função query que retorna um objeto de resposta PDOStatement que pode ser percorrido utilizando um laço foreach.

Também é possível percorrer um objeto PDOStatement utilizando o método fetch dele e tratar cada linha da consulta como um objeto.

Vejamos:


try{
    //executa a instrução de consulta
    $result = $oConexao->query("SELECT * FROM clientes");

    if($result){
        //percorre os resultados via o fetch()
        while ($item = $result->fetch(PDO::FETCH_OBJ)){
            //exibe resultado
             echo "Nome: ".$item->nome. " - " . $item->telefone . $item->email . "<br>\n";
        }
    }
}catch (PDOException $e){
    echo $e->getMessage();
}

Agora veremos um recurso muito interessante do PDO, que consiste em preparar o comando antes de executá-lo. Como era de se esperar, vamos utilizar a função do PDOStatement, a prepare(). Vejamos abaixo:


try{
    //executa a instrução de consulta
    $oConexao->beginTransaction();

    $stmt = $oConexao->prepare("INSERT INTO clientes (nome,telefone,email) VALUES (?, ?, ?)");
    $stmt->bindValue(1, "Helio");
    $stmt->bindValue(2, "33-4444-5555");
    $stmt->bindValue(3, "helio@m.com.br");
    $stmt->execute();

    $oConexao->commit();

}catch (PDOException $e){
    $oConexao->rollBack();
    echo $e->getMessage();
}

Veja que neste caso eu utilizei o método beginTransaction() do objeto pdo, nosso objeto de conexão, este método abre uma transação com o banco de dados e desliga o "autocommit". A vantagem de se utilizar dele é que a operação só é commitada depois de toda a execução. E é você que tem que escrever esta função para finalizar a transação commit(), porém se o pdo capturar alguma exceção.

Ele pula para o bloco catch e a função rollback() se encarrega de retroceder as alterações feitas no banco, assim é possível garantir a medida do possível a integridade do banco e de seus dados.

Leia mais sobre transações sem autocommit em:

http://dev.mysql.com/doc/refman/4.1/pt/commit.html

Considerações finais:

Este artigo veio para fortalecer e complementar o artigo anterior sobre pdo. Espero que tenha sido esclarecedor. E mais uma observação. No início do artigo falei a respeito de alterar um atributo do pdo com esta estrutura inserida no construtor:

array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)

Na documentação do pdo existem várias constantes como estas podendo ser utilizadas para as mais diversas coisas. Por tanto vale a pena dar uma olhada na documentação. Desta vez vou disponibilizar os arquivos necessários para a execução deste exercício. Até a próxima 😉

Download: Arquivos de Trabalho

Drive MySql de conexão para Eclipse

Posted on setembro 13, 2010

Posted by Rodrigo Ireno

Olá, neste artigo iremos focar em como utilizar o drive de conexão do Mysql na IDE eclipse. Veremos passo-a-passo como instalar, o que é uma coisa muito simples, e alguns comandos SQL com Java.

Quem já me conhece sabe que costumo escrever sobre php. Então já deve ter visto o artigo sobre PDO. E advinha em que o PDO foi baseado? Em? O Java!

Vamos aos passos:

1º - Faça download do Eclipse se não estiver instalado, neste link:
http://www.eclipse.org/downloads/packages/eclipse-ide-java-developers/heliosr

- para este artigo sugiro utilizar a versão clássica para java SE.

2º - Faça download do drive de conexão com o banco de dados mysql. No próprio site deles, neste link:
http://www.mysql.com/downloads/connector/j/

Escolha o tipo de arquivo que deseja baixar e clique em download, você será redirecionado para uma página que irá sugerir um cadastro, porém isso não é necessário, clique no link
» No thanks, just take me to the downloads!” e siga em frente para fazer download.

Depois disso você será direcionado a página com o link de download. Clique no link, como na imagem abaixo, pode ser qualquer um com as bandeiras do Brasil:

3º - Agora precisamos do Banco de dados, claro! Você pode adquirir o banco de dados gratuitamente no próprio site Mysql.com, porém sua configuração iria estender um pouco mais a coisa, e até tornar um pouco mais complicado. Para tanto, utilize um gerenciador que já instala pra você o Mysql – entre outras coisas -, e uma interface de administrador. O mais fácil e que eu sugiro é o xampp.

O xampp é gratuito e de fácil instalação. Depois de instalado, para acionar o banco de dados mysql é só clicar no botão "start", e para usar o phpMyAdmin (interface para administração do banco) é preciso iniciar também o Apache com "start".

Veja um artigo utilizando o xampp.

Você pode fazer download do xampp neste link:
http://www.baixaki.com.br/download/xampp.htm

Bom, se tudo ocorreu bem até agora, você já deve ter os ingredientes:
Eclipse, drive de conexão, xampp  (cujo "m" da sigla é de Mysql)

Vamos por a mão na massa então! Instale o xampp e o eclipse.

Com o xampp iniciado clique em start para o mysql e o Apache;

Depois clique no botão admin para o mysql;

Ele irá abrir em seu browser padrão o phpMyAdmin. Crie um banco de dados com o nome tutorial.

não iremos entrar em maiores detalhes no phpMyAdmin, pois este não é o foco deste artigo, conteudo sobre phpMyAdmin

Interface phpmyadmin

Depois de criado, ele irá aparecer na lateral esquerda do browser. Clique no nome do Banco de dados que você acabou de criar com o nome tutorial e depois na aba SQL, à direita. E excute esta query, ou crie uma tabela equivalente.


CREATE TABLE IF NOT EXISTS `cliente` (

`id` int(11) NOT NULL AUTO_INCREMENT,

 `nome` varchar(80) NOT NULL,

 `fone` varchar(80) NOT NULL,

PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Após isso crie um novo projeto no eclipse com o nome de sua preferência. Dentro deste projeto crie as seguintes classes abaixo.

Antes de tudo, vamos esclarecer que este artigo não visa utilizar nenhum padrão de desenvolvimento específico. É somente um “Oi banco de dados”

package tutorial;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Conexao {

	// Carrega driver JDBC
	static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e);
		}
	}

	//Obtem conexao com banco de dados
	public Connection obtemConexao() throws SQLException{
		return DriverManager.getConnection(
				"jdbc:mysql://localhost/tutorial","root","");
	}
}

package tutorial;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.ResultSet;

public class Cliente {

	private int idCliente;
	private String nome;
	private String fone;

	public Cliente(){

	}

	public Cliente(int idCliente) {
		this.idCliente = idCliente;
	}

	public Cliente(String nome, String fone) {
		this.nome = nome;
		this.fone = fone;
	}

	public int getIdCliente() {
		return idCliente;
	}

	public void setIdCliente (int idCliente) {
		this.idCliente = idCliente;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getFone() {
		return fone;
	}

	public void setFone(String fone) {
		this.fone = fone;
	}

	//  Inclusao de clientes
	public void incluir(Connection conn) {

		//Armazena a string contento o comando sql numa variavel.
		//Repare nos pontos de interrogação, pois eles serão preenchidos!

		String sqlInsert = "INSERT INTO cliente(nome, fone) VALUES ( ?, ?)";

		//inicio um objeto que prepara a instrução a ser executada.
		 //Veja o 'null'.Ele ainda está vazio

		PreparedStatement stm = null;
		try {

			 	//Agora sim. Atraves do objeto Connection eu
			 	//recupero o objeto 'preparador de instrução'.
			 	//veja que já inseri a variavel que tem o comando sql!

			stm = conn.prepareStatement(sqlInsert);

			 //Lembra dos pontos de interrogação, no seu comando sql?
			 //o método setString seta estes pontos de interrogação.
			 //substituindo-os pelo valor que vem no segundo parâmetro.
			 //Portanto...

			//Aqui, substitui a primeira interrogação pelo nome do cliente
			stm.setString(1, getNome());

			//Aqui, substitui a segunda interrogação pelo fone (telefone) do cliente
			stm.setString(2, getFone());

			//E finalmente depois de tudo devidamente preparado ele chama
			// o comando execute()
			stm.execute();

		} catch (Exception e) {
			//Caso tenha uma exceção printa na tela
			e.printStackTrace();
				try {
					//Aqui ele 'tenta' retroceder, na ação que deu errado.
					// quese um Ctrl+Z da vida.
					conn.rollback();
				} catch (SQLException e1) {
					System.out.print(e1.getStackTrace());
				}
		} finally {
			// Comando finally sempre é executado
			if (stm != null) {
				try {
					// Encerra as operações.
					stm.close();
				} catch (SQLException e1) {
					System.out.print(e1.getStackTrace());
				}
			}
		}
	}

	public void buscar(Connection conn) {

		String sqlSelect = "SELECT nome, fone FROM cliente WHERE cliente.id = ?";

		PreparedStatement stm = null;

		  // Aqui temos uma nova estrela no pauco.
		  // O objeto ResultSet é responsavel por manipular
		  // os resultados de uma query de busca.

		ResultSet rs = null;

		try {
			//vide explicaçao anterior
			stm = conn.prepareStatement(sqlSelect);

			//ponto de interrogação por valor getIdCliente()
			stm.setInt(1, getIdCliente());

			//O comando abaixo retorna um objeto ResultSet
			//com os valores dos dados buscados.

			rs = stm.executeQuery();

			//use next() para verificar se ele veio preenchido
			//de dados. Ele também pode ser usado em um while,
			//para querys que resultem em mais de um registro.

			if (rs.next()){

				//Acima no nosso select foi declarado:
				//SELECT nome, fone FROM..
				//portanto o 1 = nome e o
				//2 = fone

				//getString(1) refere-se ao atributo 'nome' da nossa query
				this.setNome(rs.getString(1));

				//Já o getString(2) refere-se ao atributo 'fone'
				this.setFone(rs.getString(2));
			}

		} catch (Exception e) {
			e.printStackTrace();
				try {
					conn.rollback();
				} catch (SQLException e1) {
					System.out.print(e1.getStackTrace());
				}
		} finally {
			if (stm != null) {
				try {
					stm.close();
				} catch (SQLException e1) {
					System.out.print(e1.getStackTrace());
				}
			}
		}
	}
}

package tutorial;

import java.sql.SQLException;
import java.sql.Connection;

 public class Teste {

    public static void main(String[] args) {

      Connection conn = null;

      Cliente cl;

      try {

      // obtem conexao com o banco
    	 Conexao bd = new Conexao();
         conn = bd.obtemConexao();

         conn.setAutoCommit(false);

      //  Inclusao do Primeiro Cliente
         cl = new Cliente("Mariana Soares", "1127991999");
         cl.incluir(conn);

      // Inclusao do Segundo Cliente
         cl = new Cliente();
         cl.setNome("João Neves");
         cl.setFone("1160606161");
         cl.incluir(conn);

      // Inclusao do Terceiro Cliente
         cl = new Cliente("Maria Oliveira", "1121212121");
         cl.incluir(conn);

      // efetiva inclusoes
         conn.commit();
         System.out.println("Inclusão concluída");
         System.out.println("Buscando...");

      // Busca Cliente com id 2
         cl = new Cliente(2);
         cl.buscar(conn);

         String saida = "Nome: "+cl.getNome()+
         				 "\nTelefone: "+cl.getFone()+
         				 "\nid: "+cl.getIdCliente();

         System.out.println(saida);
      }
          catch (Exception e) {
            e.printStackTrace();
            if (conn != null) {
               try {
                  conn.rollback();
               }
                   catch (SQLException e1) {
                     System.out.print(e1.getStackTrace());
                  }
            }
         }
      finally {
         if (conn != null) {
            try {
               conn.close();
            }
                catch (SQLException e1) {
                  System.out.print(e1.getStackTrace());
               }
         }
      }
      System.exit(0);
    }
}

Veja minha estrutura para este projeto:

Depois que as classes já estiverem ok iremos adicionar aquele drive ao nosso projeto. Para isso clique com o botão direito sobre o seu projeto.
Siga o caminho: Build Path > Configure Build Path >
escolha a aba Libraries.
Agora clique no botão “Add External JARs...”
Encontre o drive que você baixou, com extensão “.JAR”. Clique nele, depois em Abrir.
(ele precisa estar descompactado, ele era um .zip lembra?)
Pronto seu driver já foi instalado.

Para testar a coisa toda:

O xampp deve estar ligado, com mysql e apache iniciados. phpMyAdmin aberto, para você checar as alterações na sua tabela.

O script foi feito para inserir  três clientes toda vez que for rodado, e buscar um pelo id. Rode a classe Teste, agora veja o resultado no phpMyAdmin. Para atualizar a visualização, basta clicar na aba visualizar.

Esse artigo fica por aqui, qualquer dúvida postem. Obrigado e até a próxima!

Acesso a banco de dados com php

Posted on julho 28, 2010

Posted by Rodrigo Ireno

Olá, neste artigo vamos abordar conexão com banco de dados usando php. Sei que até agora vimos muitas coisas relacionadas a orientação a objetos, porém para fim de simplificar o entendimento vou abordar de forma procedural. Programar de forma procedural. Ou seja, não orientado a objetos. Calma! Veremos exemplos orientados a objetos também, aqui é só pra centralizar a idéia no processo de conectar. O que no final das contas é uma coisa muito simples.

Se você vem acompanhando meus artigos já deve ter visto algo sobre o xampp, mas se você estava sapeando pelo Google e parou por aqui, eis um link de um artigo que fala um pouco sobre o xampp:  Hello world em php. Ele é um aplicativo que instala um kit básico pra desenvolvimento em php. Entre os softwares instalados está o banco de dados MySql. Que é o que nos interessa neste artigo, porque vamos nos conectar com ele.

Crendo eu, que você já tem o xampp vamos prosseguir. Acesse o http://localhost e depois o phpMyAdmin. Este aplicativo é feito em php e usaremos ele para administrar nosso banco de dados.

Para manipular um banco de dados utiliza-se uma linguagem própria. Esta linguagem é o SQL. É muito fácil encontrar conteúdo sobre SQL, eis que pelo menos o banco de dados MySQL tem documentação online. Outros bancos de dados também usam SQL, porém existe uma variação da sintaxe. Para nosso exemplo utilize o código abaixo para criar o banco de dados e a tabela que iremos utilizar.


/* Cria o banco de dados */

CREATE DATABASE objota;

/*
	O código abaixo cria a tabela clientes.

	veja que os comandos são bem explícitos. (cria a tabela se ela não existe)
*/

CREATE TABLE IF NOT EXISTS objota.clientes (
  id int(11) NOT NULL AUTO_INCREMENT,
  nome varchar(50) NOT NULL,
  telefone varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

/* Insere alguns registros na tabela */

INSERT INTO objota.clientes (id, nome, telefone) VALUES
(1, 'Carlos', '3333-4444'),
(2, 'Mario', '5555-6666'),
(3, 'Marcela', '7894-6543'),
(4, 'Gustavo', '1535-5847');

Com o phpMyAdmin aberto em seu navegador copie este código SQL, selecione a aba SQL no menu da página inicial cole este código no campo de input e após isso clique em executar. Este código criará um banco de dados com o nome objota e uma tabela com o nome clientes com os seguintes atributos: id, nome, telefone.

Como se trata de um exemplo a tabela já virá ”populada”, ou seja, com algum conteúdo. Feito isso nosso banco de dados já existe. Iremos então usar um comando para recuperar estes dados. Mas antes, a tal conexão.

Conectando ao banco de dados

Para se conectar a um banco de dados é necessário possuir:

  • Nome do banco de dados
  • Nome do usuário de banco de dados
  • Endereço do banco de dados
  • Senha
  • Porta

Como se trata de uma conexão local o Endereço do banco no caso é sua própria máquina. Você pode referenciar ele pelo nome localhost. O nome do banco de dados é objota, neste exemplo. Por padrão no phpMyAdmin o nome padrão de usuário é root. Senha até então não existe, então simplesmente não forneça nada. Porta padrão é 3306. Vejamos o código abaixo:

<?php

$con = mysqli_connect("localhost","root","","objota","3306");

if(!$con){
	echo "Ops! <br/>";
}
else{
	// Se conectou posso fazer uma busca por dados.
	echo "Conectou!!! <br/>";

	//Vejamos um comando SQL para selecionar os dados de nossa tabela.
	$sql = "SELECT id, nome, telefone
			FROM clientes";

	//Forneço o ponteiro de conexão $con e o comando SQL vai no segundo parâmetro
	$rs =  mysqli_query($con, $sql);

	//Extraímos os dados da resource resultante em um array
	$dados = mysqli_fetch_array($rs);

	//Pronto!! eis os dados obtidos
	var_export($dados);
}

?>

Detalhando os acontecimentos. Primeiro me conectei ao banco usando a função mysqli_connect(). Faço uma breve verificação, caso esteja tudo bem prosseguimos com o acesso. Armazeno na variável $sql um comando SELECT que traz todo o conteúdo da tabela.
Logo em seguida utilizo a função mysqli_query($con, $sql) ,  repare que passo como primeiro parâmetro o ponteiro de conexão, em seguida vem a query (comando SQL). Essa função me retorna uma resource , que tecnicamente ainda não são os dados que eu pedi. Afinal quero nome e telefone da tabela. Para extrair desta resource os dados que eu quero, é preciso usar a função mysqli_fetch_array($resource) , veja que forneço a resource como parâmetro e ele finalmente me retorna um array com os dados que eu requisitei.

Obs: Neste exemplo fiz uso da função var_export($var) para mostrar todo o conteúdo do array na tela, muitos programadores usam isto para verificar o conteúdo de uma variável a fim de debugar o um código.

Porém abaixo segue mais um código que faz o mesmo que o código acima. Porém ele acessa os dados do array com um loop e mostra na tela de forma mais “apresentável”.

<?php

$con = mysqli_connect("localhost","root","","objota","3306");

if(!$con){
	echo "Ops! <br/>";
}
else{
	// Se conectou posso fazer uma busca por dados.
	echo "Conectou!!! <br/>";

	//Vejamos um comando SQL para selecionar os dados de nossa tabela.
	$sql = "SELECT id, nome, telefone
			FROM clientes";

	//Forneço o ponteiro de conexão $con e o comando SQL vai no segundo parâmetro
	$rs =  mysqli_query($con, $sql);

	//Extraímos os dados da resource resultante em um array
	while($dados = mysqli_fetch_array($rs)){

		// Com o uso do caracter ponto "."
		// é possível concatenar (unir) trechos de string
		echo "<b>Nome:</b> ".$dados['nome']." <b>Telefone:</b> ".$dados['telefone']."<br/>";
	}
}

?>

extra: veja este vídeo que mostra o phpMyAdmin em uso video

Bom pessoal, este artigo acaba aqui, porém ainda tem muita coisa pra falar e exemplificar. Foi apenas um breve exercício, mas espero ter ajudado em algo. No próximo artigo adentraremos um pouco mais em orientação a objetos, e veremos futuramente acesso a banco de dados usando um objeto. Dúvidas?