SlideShare uma empresa Scribd logo
Tecnologia em Sistemas para Internet
Componente Curricular: Desenvolvimento para Servidores I
015 – Programação Orientada a Objetos e PHP
Conexão com Bancos de Dados usando PDO – PHP Data Objects
Professor: Jorge Luís Gregório | e-mail: jorge.gregorio@fatec.sp.gov.br
@jlgregorio81 Jorge Luís Gregório
Um pouco de história...
• A comunidade PHP sempre foi muito grande e muito ativa no mundo todo,
desta forma, o PHP cresceu com uma grande diversidade de bibliotecas
construídas para resolver problemas muito específicos, principalmente
quando o assunto é banco de dados.
• Existem diversos SGBDs no mercado, entre eles, os mais populares são
MySQL, Firebird, Postgres, entre outros. Desta forma, o PHP, no ápice do
seu crescimento fornecia bibliotecas diferentes com funções diferentes
para bancos de dados diferentes.
• Apesar de resolver problemas de desenvolvedores de bancos de dados
específicos, essa solução limitava o PHP, pois, ao ser considerada a
mudança do SGBD de uma aplicação, o desenvolvedor teria que adaptar
e/ou alterar todo a lógica de acesso ao banco de dados, pois o PHP
fornecia funções específicas para cada banco.
• Face a essa limitação, surge o PDO – PHP Data Objects
PDO – PHP Data Objects
• O PDO fornece uma API limpa e consistente que visa
unificar a maioria das características e funções
presentes nas extensões dos bancos de dados aos
quais o PHP suporta (Dall’Oglio, 2009, pág. 159)
• A PDO unifica as chamadas de métodos e, de acordo
com o banco de dados selecionado, faz a delegação
para a extensão específica do banco de dados.
• A PDO é totalmente orientada a objetos, diferente das
extensões específicas dos bancos de dados que ainda
possui o modelo procedural de chamada de funções.
PDO e as extensões para acesso a
bancos de dados do PHP
PDO
Extensão do
MySQL
Extensão do
PostgreSQL
Extensão do SQLite
Banco de dados
Aplicação Web
Ativando extensões no WAMP
• Por padrão, a extensão para conexão com banco de
dados MySQL vem ativa no Wamp. Caso deseja usar o
Postgres, é necessário ativar a exetensão.
– Clique no ícone do WAMP na bandeja do sistema,
selecione a opção PHP, depos PHP Extensions e ative as
opções php_pdo_pgsql e php_pgsql
• Para fazer manualmente, é necessário abrir o arquivo
php.ini na pasta do servidor Apache e retire o
comentário (símbolo ;) das linhas onde se encontra
digitado
extension=php_pdo_pgsql.dll
extension=php_pgsql
Testando se o PDO/PGSQL está ativo
• Depois de ativar as extensões do Postgres no PHP é
necessário fazer um teste para verificar se estão ativas;
• Crie um arquivo index.php e digite o seguinte código
nele:
phpinfo();
A função phpinfo mostrará todas as configurações do
servidor Apache e quais drivers de conexão foram
carregados. Localize as palavras PDO, pdo_pgsql e pgsql.
Se todas estiverem presentes, tanto o driver de conexão
com o Posgres quanto o PDO estão ativos.
Verificando a configuração
Abrindo o index.php no browser
Erro persistente!
• Caso os drivers/extensões não tenham sido carregados, provavelmente será
necessário editar o arquivo de configuração do Apache inserindo uma linha de
comando para carregar a DLL (Dynamic Link Library) de conexão com o Postgres.
• Essa DLL fica na pasta do wamp no seguinte caminho:
binphp<versão_do_php>libpq.dll
Abra o arquivo de configuração do Apache (httpd.conf) que fica na pasta do wamp no
seguinte caminho:
binapache<versão_do_apacheconfhttpd.conf
Logo após a última linha com o comando LoadModule, adicione a seguinte linha de
comando:
LoadFile “<raiz_do_wamp>/bin/php/<versão_do_php>/libpq.dll”
Criando um banco de dados
• Abra o PgAdmin (Postgres) e crie um banco de
dados com o nome ‘database’ (sem aspas)
• Clique no link para baixar o script para a
criação das tabelas:
– Clique aqui!
Powered by:
String de conexão
Banco de
Dados
String de conexão
FireBird new PDO(“firebird:dbname=C:base.GDB”,
“SYSDBA”, “masterkey”);
MySQL new
PDO(‘mysql:unix_socket=/tmp/mysql.sock;host=loc
alhost;port3306;dbname=livro’,’user’,’senha’)
Postgres new
PDO(‘pgsql:dbname=example;user=user;password=se
nha;host=localhost);
Adaptado de Dall’Oglio, 2009, pág. 160
Criando uma classe de conexão
namespace util;
use PDO;
/**
* Description of Connection
*
* @author JorgeLuis
*/
class Connection {
//..constantes para conexão com o Postgres
const DBNAME = 'database';
const USER = 'postgres';
const PASSWORD='postdba';
const HOST = 'localhost';
const PORT = 5432;
/**
* Retorna um objeto do tipo PDO pronto para executar instruções SQL no banco de dados
* @return PDO
* @throws utilPDOException
*/
public static function getConnection(){
try {
return new PDO("pgsql:dbname=".self::DBNAME.";user=".self::USER .
";password=".self::PASSWORD.";host=".self::HOST .
";port=".self::PORT);
} catch (PDOException $ex) {
throw $ex;
}
}
}
Inserindo dados
O método exec da classe PDO é capaz de executar uma instrução SQL diretamente no banco de
dados. O retorno do método é um número inteiro contendo a qtde de linhas linhas que foram
atualizadas no banco de dados.
require_once 'autoload.php';
use utilConnection;
try {
//..pega um objeto PDO
$db = Connection::getConnection();
} catch (Exception $ex) {
//..trata a exceção
echo $ex->getMessage() . " - " . $ex->getCode();
}
//..inserindo na tabela cidade
$linhas = $db->exec("insert into cidade (nome, uf, cep) values('Urânia','SP','15760000')");
if ($linhas > 0)
echo 'Dados inseridos!<br>';
else
echo 'Erro!';
Atualizando registros
O comando exec pode ser usado também para comandos de update:
require_once 'autoload.php';
use utilConnection;
//..pega um objeto PDO
$db = Connection::getConnection();
//..executa o comando update
$linhas = $db->exec("update cidade set nome='Londrina', uf='PR' where id_cidade = 1");
if($linhas > 0)
echo 'Dados atualizados com sucesso!<br>';
else
echo 'Erro!<br>';
Excluindo registros
require_once 'autoload.php';
use utilConnection;
//..pega um objeto PDO
$db = Connection::getConnection();
//..executa o comando delete
$linhas = $db->exec("delete from cidade where id_cidade = 1");
if($linhas > 0)
echo 'Dados excluídos com sucesso!<br>';
else
echo 'Erro!<br>';
Listando registros
• Para listar registros, isto é, executar uma consulta no banco de dados, o método
query deverá ser invocado. Se não houver dados que satisfaçam a consulta, o
retorno do método será false, caso contrário, será retornado um objeto
PDOStatement que é um resultset no formato de um array composto de outros
arrays.
require_once 'autoload.php';
use utilConnection;
//..pega um objeto PDO
$db = Connection::getConnection();
//..executa a consulta
$resultSet = $db->query('select * from cidade order by nome');
//..se houver resultSet, então itera-o mostrando os campos da consulta
if($resultSet){
foreach ($resultSet as $reg) {
echo $reg['id_cidade'] . ' - ';
echo $reg['nome'] . ' - ';
echo $reg['uf'] . ' - ';
echo $reg['cep'] . '<br>';
}
}
Listando registros
• É possível determinar outros formatos para
retornar os dados usando a função FETCH e
passando um parâmetro de acordo com a
tabela:
Parâmetros Descrição
PDO::FETCH_ASSOC Retorna um array indexado pelo nome da coluna (padrão)
PDO::FETCH_NUM Retorna um array indexado pela posição numérica da coluna
PDO::FETCH_BOTH Retorna um array indexado pelo nome da coluna e pela
posição numérica da mesma.
PDO::FETCH_OBJ Retorna um objeto (StdClass), de modo que cada coluna é
acessada como um propriedade.
Adaptado de Dall’Oglio, 2009, pág. 162
Listando registros - objetos
require_once 'autoload.php';
use utilConnection;
//..pega um objeto PDO
$db = Connection::getConnection();
//..executa a consulta
$resultSet = $db->query('select * from cidade order by nome');
if($resultSet){
while ($reg = $resultSet->fetch(PDO::FETCH_OBJ)){
echo $reg->id_cidade . ' - ' .
$reg->nome . ' - ' .
$reg->uf . ' - ' .
$reg->cep . '<br>';
}
}
Listando registros – índice numérico
require_once 'autoload.php';
use utilConnection;
//..pega um objeto PDO
$db = Connection::getConnection();
//..executa a consulta
$resultSet = $db->query('select * from cidade order by nome');
if($resultSet){
while ($reg = $resultSet->fetch(PDO::FETCH_NUM)){
echo $reg[0] . ' - ' .
$reg[1] . ' - ' .
$reg[2] . ' - ' .
$reg[3] . '<br>';
}
}
Este modo é recomendável para simplificar a referência aos atributos quando estes
são conhecidos. O parâmetro PDO::BOTH permite que os atributos sejam
referenciados tanto por índices numéricos, quanto por chaves.
Tratamento de erros
• A classe PDO possui um método chamado setAttribute ao qual é possível
configurar, entre outros recursos avançados, o modo de como os erros
gerados pelo objeto serão tratados.
• É recomendável configurar a classe de conexão para gerar exceções, pois
assim é possível lançar e/ou tratar os erros de forma mais elegante através
dos já conhecidos blocos try..catch.
• A exceção gerada é uma instância de PDOException, isto é, uma exceção
específica para erros de bancos de dados.
• Exemplo:
//..pega um objeto PDO
$db = Connection::getConnection();
//..seta o modo de erros
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
A partir de agora, o objeto $db irá lançar exceções, caso aconteçam.
Exemplo completo
try {
//..pega um objeto PDO
$db = Connection::getConnection();
//..seta o modo de erros
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//..executa a consulta - nome da tabela cidade está errado – vai gerar erro!
$resultSet = $db->query('select * from cidades order by nome');
if ($resultSet) {
while ($reg = $resultSet->fetch(PDO::FETCH_BOTH)) {
echo $reg[0] . ' - ' .
$reg[1] . ' - ' .
$reg['uf'] . ' - ' .
$reg['cep'] . '<br>';
}
}
} catch (PDOException $ex) {
//..mostra a mensagem de erro
echo $ex->getMessage();
}
Modificando a classe Connection
• Para fazer com que a classe Connection retorne um objeto PDO pronto a gerar exceções, segue uma nova
proposta.
namespace util;
use PDO;
/**
* Description of Connection
*
* @author JorgeLuis
*/
class Connection {
//..constantes para conexão com o Postgres
const DBNAME = 'database';
const USER = 'postgres';
const PASSWORD='postdba';
const HOST = 'localhost';
const PORT = 5432;
/**
* Retorna um objeto do tipo PDO pronto para executar instruções SQL no banco de dados
* @return PDO
* @throws utilPDOException
*/
public static function getConnection(){
try {
//..pega um objeto PDO
$connection = new PDO("pgsql:dbname=".self::DBNAME.";user=".self::USER.
";password=".self::PASSWORD.";host=".self::HOST.";port=".self::PORT);
//..configura para gerar exceções sempre que um erro ocorrer
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//..retorna o objeto PDO;
return $connection;
} catch (PDOException $ex) {
throw $ex;
}
}
}
Exemplo de tratamento de erros
require_once 'autoload.php';
use utilConnection;
try {
//..pega um objeto PDO
$db = Connection::getConnection();
//..executa a consulta - nome da tabela cidade está errado – vai gerar Exceção
$resultSet = $db->query('select * from cidades order by nome');
if ($resultSet) {
while ($reg = $resultSet->fetch(PDO::FETCH_BOTH)) {
echo $reg[0] . ' - ' .
$reg[1] . ' - ' .
$reg['uf'] . ' - ' .
$reg['cep'] . '<br>';
}
}
} catch (PDOException $ex) {
echo $ex->getMessage();
}
Transações
Uma transação representa uma interação entre a
aplicação e o sistema de banco de dados tratada de
forma única e independente. Pense em uma
transação financeira de transferência de fundos.
Este tipo de transação necessita de um grande
cuidado pois, do contrário, uma conta pode ser
debitada e a outra não ser creditada, ou vice-versa.
Uma transação é uma sequência de trabalho que
tem um ponto de início e de fim bem definidos [...]”
DALL’OGLIO, 2009, pág. 206
Propriedades de Transações - ACID
• Atomicidade: uma transação pode envolver uma ou mais interações com
o banco de dados, porém deve ser vista como uma única operação. Se
uma delas falhar, os dados não refletirão o mundo real então, toda a
operação deverá ser revertida (rollback). Executa tudo ou nada. Sem
operações incompletas.
• Consistêcia: após a transação, os dados devem permanecer íntegros, ou
seja, com todas as suas restrições (chave primária, check, etc) intactas.
• Isolamento: as transações devem ser executadas isoladas de outras
transações, pois pode ser que um registro seja acessado por diversas
transações ao mesmo tempo (venda de um produto). O resultado da
transação só deve ser visível após o seu término.
• Durabilidade: deve haver a garantia de que os dados serão persistentes
após o término da transação, ou seja, ela não será desfeita e/ou perdida
por qualquer que seja o motivo.
Sintaxe
try{
//..inicia a transação
PDOObject->beginTransaction();
//..instrução SQL 01
//..instrução SQL 02
//..instrução SQL 03
//..instrução SQL n...
//..confirma a transação
PDOObject->commit();
}
catch(PDOException $ex){
//..retorna ao estado inicial caso aconteça algum erro
PDOObject->rollBack();
}
Exemplo
• No banco de dados, a tabela pessoafisica é uma
especialização da tabela pessoa, ou seja, para
cadastrar uma pessoa física é necessário primeiro
a inserção dos dados na tabela pessoa e, após
obter o nº do id inserido, é necessário inserir o
registro específico na tabela pessoafisica.
• Se qualquer uma das operações falhar no
momento da confirmação (commit), o sistema
deverá cancelar a transação (rollback).
• Os dados deverão ser inseridos nas duas tabelas
ou em nenhuma (atomicidade).
Código-fonte comentado
require_once 'autoload.php';
use utilConnection;
try{
//..pega uma conexão
$connection = Connection::getConnection();
//..inicia a transação
$connection->beginTransaction();
//..inicia as operações da transação
//..executa a instrução SQL para inserção em pessoa
$connection->exec("insert into pessoa(nome, id_cidade) values ('Peter Parker', 2);");
echo 'Pessoa Inserida! <br>';
//..pega o id do registro inserido em pessoa para inserí-lo em pessoafisica
$id = $connection->lastInsertId("seq_pessoa");
echo "ID inserido: $id <br>";
//..executa a instrução SQL para a inserção em pessoafisica
$connection->exec("insert into pessoafisica values ($id, 'M', '111','222','Rua XYZ','15999000');");
echo 'Pessoa Física Inserida! <br>';
//..confirma a transação
$connection->commit();
}
catch (PDOException $ex){
//..Se gerar exceção, mostra o erro e executa um rollback.
echo 'Erro na transação: ' . $ex->getMessage() . '<br>';
$connection->rollBack();
}
Dica: Para verificar se o controle de transação está realmente dando certo, crie um erro em uma
das instruções SQL, na primeira ou na segunda. Com erros, a lógica acima cairá no bloco catch e o
rollback será executado desfazendo as alterações.
Atividade Prática
• Criar uma aplicação simples que cadastre e liste
os dados de um formulário
• Dados:
– Nome (campo de texto)
– Sexo (campo select)
– Formação (campo select)
• Ensino fundamental
• Ensino médio
• Superior
• Pós graduação
• Outros
Mapeamento Objeto-Relacional
• Persistência
– Persistir quer dizer perdurar, resistir ao tempo. Em
uma aplicação, persistir significa fazer com que os
objetos do modelo de negócio sejam “gravados” em
um local externo à aplicação e que, principalmente,
permita sua posterior recuperação.
– Objetos existem apenas durante um certo período de
tempo dentro dos limites da aplicação, desta forma, é
extremamente importante seu armazenamento.
Mundo OO vs Mundo Relacional
[...] existem diversos conceitos da orientação a objetos
para os quais o modelo relacional simplesmente não
oferece suporte, então temos uma diferença de conceito.
Os bancos de dados foram construídos para armazenar
dados, ao passo que, no paradigma orientado a objetos,
além de dados (atributos), temos comportamento
(métodos) e outras estruturas complexas. Dessa forma, é
necessário utilizar alguma ferramenta de compatibilidade
entre os dois modelos, que geralmente implementam
algum técnica de mapeamento objeto-relacional. [...]
DALL’OGLIO, 2009, pág. 222
Mundo OO vs Mundo Relacional
• Mundo Relacional
– Tabelas: entidade que
armazena dados
– Registros: cada dado ou
conjunto de dados de uma
tabela real ou gerada por
SQL
– Chaves primárias:
responsáveis por:
• Fazer com que um registro
seja único
• Fazer com que as tabelas se
relacionem através de
ligação com chaves
estrangeiras
• Mundo OO
– Objetos: armazenam dados
e são capazes de realizar
tarefas
– Listas: conjuntos de
objetos
– Os relacionamentos são
feitos por associações:
• Associação simples
• Composição
• Agregação
Mundo OO vs Mundo Relacional
• Padrões para mapeamento objeto-relacional:
– Identity Field: campo autoincremento para chave primária/estrangeira
– Foreign Key Mapping: composição (relacionamento “forte” todo/parte) no
mundo OO pode ser realizada através de chaves estrangeiras.
– Association Table Mapping: agregação (relacionamento “fraco” todo/parte )
também pode ser mapeado como chaves estrangeiras.
– Herança
• Single Table Inheritance: as classes são mapeadas para uma única tabela contendo todos os
atributos comuns da hierarquia.
• Concrete Table Inheritance: as classes são mapeadas para diversas tabelas, cada classe possui
uma tabela de forma independente.
• Class Table Inheritance: e criada uma tabela para cada classe na estrutura da hierarquia. Após
isso, cria-se uma generalização/especialização através de pares de chaves primárias.
Maiores detalhes em Dall’Oglio, pág. 222-231.
DAO – Data Access Object
• O padrão de projeto DAO propõe a criação de uma camada de
acesso a dados independente de outras camadas da aplicação, ou
seja, os objetos DAO possui a responsabilidade de persistir objetos
em bancos de dados, realizando, o mapeamento objeto-relacional
(Object-Relational Mapping).
• Além da persistência (inserts e updates), os objetos DAO também
podem recuperar dados através de consultas SQL e retornar apenas
objetos de negócio (model) para a aplicação.
• Vantagens:
– Isolar a lógica de acesso e manipulação de dados de outros
componentes do sistema melhora a reusabilidade, escalabidade e
manutenabilidade do código.
DAO – Data Access Object
model
Classe1 Classe2
* *
Classe3 Classe4
1 *
+findById()
+persist()
+query()
+delete()
DAO
Banco de
dados
Objetos model Instruções SQL
Dados
Objetos
Exemplo
• Baixar o código-fonte comentado no link
abaixo:
– Clique aqui!
Powered by:
Discussão – a camada model
Discussão – a camada dao
Discussão – métodos DAO
• Os objetos DAO devem implementar a interface Idao, então,
surgem os seguintes métodos:
– persist($modelObject)
• Insere e/ou atualiza um registro no banco de dados mediante um objeto
model informado. O objeto deverá ser mapeado em dados relacionais e
persistido no Banco de Dados.
– delete($id)
• Exclui um registro baseado no id informado
– query($field = null, $like=null)
• Realiza uma query do tipo “selecionar tudo” ou usando um campo e uma
cláusula ‘like’ como filtros. Retorna um ArrayObject (array de objetos)
– findById($id)
• Recupera um registro mediante o id informado, mapeia-o em objeto e retorna
para a aplicação.
O que vem depois???
• Agora que a camada DAO está pronta, é
necessário integrá-la a sua aplicação.
• MVC – Model/View/Controller
– Padrão de Projeto (Design Pattern) que divide uma
aplicação em 3 camadas distintas.
– O padrão DAO combina muito bem com o MVC.
Bibliografia recomendada
DALL’OGLIO, Pablo. Capítulo 3: Manipulação de dados. In: ________. PHP:
programando com orientação a objetos. 2. ed. São Paulo: Novatec, 2009. p. 154-220.
Manual do PHP. PHP Data Objects. Disponível em <http://php.net/manual/pt_BR/
book.pdo.php> Acesso em 20 jan. 2015.
Manual do PHP. PHP::setAttribute. Disponível em <http://php.net/manual/pt_BR/
pdo.setattribute.php> Acesso em 20 jan. 2015.

Mais conteúdo relacionado

PPTX
JS Event Loop
PPTX
E2E test con Cypress
PDF
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
PPT
Auto motion in comber
PDF
Trace memory leak with gdb (GDB로 메모리 누수 찾기)
PDF
Teste de performance com JMeter: como criar e executar os testes em aplicaçõe...
PDF
[JWPA-1]의존성 주입(Dependency injection)
PDF
ReactorKit으로 단방향 반응형 앱 만들기
JS Event Loop
E2E test con Cypress
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
Auto motion in comber
Trace memory leak with gdb (GDB로 메모리 누수 찾기)
Teste de performance com JMeter: como criar e executar os testes em aplicaçõe...
[JWPA-1]의존성 주입(Dependency injection)
ReactorKit으로 단방향 반응형 앱 만들기

Mais procurados (7)

PPTX
The Art of Clean code
PPTX
Observer Software Design Pattern
PDF
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
PPTX
Mocking with Mockito
PPTX
Noman Terry Towel Mills Ltd.
PPTX
Principles of knitting Technology.pptx
PDF
Reactive Extensionsで非同期処理を簡単に
The Art of Clean code
Observer Software Design Pattern
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Mocking with Mockito
Noman Terry Towel Mills Ltd.
Principles of knitting Technology.pptx
Reactive Extensionsで非同期処理を簡単に
Anúncio

Semelhante a Dsi 015 - poo e php - conexão com bancos de dados usando pdo (20)

PPTX
PDO: TRABALHANDO COM BANCO DO JEITO CERTO
PDF
Pdo do PHP Palestra
PDF
Palestra de PDO
PPTX
Conexões eficientes em banco de dados com PHP
PPTX
Pdo Apresentação Básica
ODP
Prog web 07-pdo
PDF
Palestra PHPSP+Locaweb 2014 - PDO
PDF
Aula 01 PHP+MySQL - LabMM4
PDF
LabMM4 (T16 - 12/13) - PHP + MySQL
ODP
Prog web 05-php-mysql
PPTX
Banco de dadados MySQL com PHP
PPT
PDO - PHP Data Object
PPTX
Fundamentos da Programação PHP OO - Aula 3
PDF
Apontamentos psi m18
PPTX
NotORM
PPTX
Aula 1 - Curso de PHP/CI e Tecnologias Relacionadas
PDF
PHP e PostgreSQL: Um é pouco, dois é bom, três é demais
PDF
PHP e PostgreSQL - Dois Elefantes trabalham muito mais !
KEY
Orientação a Objetos com PHP
PDF
PHP e MySQL para iniciantes
PDO: TRABALHANDO COM BANCO DO JEITO CERTO
Pdo do PHP Palestra
Palestra de PDO
Conexões eficientes em banco de dados com PHP
Pdo Apresentação Básica
Prog web 07-pdo
Palestra PHPSP+Locaweb 2014 - PDO
Aula 01 PHP+MySQL - LabMM4
LabMM4 (T16 - 12/13) - PHP + MySQL
Prog web 05-php-mysql
Banco de dadados MySQL com PHP
PDO - PHP Data Object
Fundamentos da Programação PHP OO - Aula 3
Apontamentos psi m18
NotORM
Aula 1 - Curso de PHP/CI e Tecnologias Relacionadas
PHP e PostgreSQL: Um é pouco, dois é bom, três é demais
PHP e PostgreSQL - Dois Elefantes trabalham muito mais !
Orientação a Objetos com PHP
PHP e MySQL para iniciantes
Anúncio

Último (20)

PDF
COBITxITIL-Entenda as diferença em uso governança TI
PPTX
Programação - Linguagem C - Variáveis, Palavras Reservadas, tipos de dados, c...
PPTX
Curso de Java 13 - (JavaEE (JSP e Servlets)).pptx
PDF
Mergulho profundo técnico para gestão de transportes no SAP S/4HANA, S4TM6 Col14
PPTX
Aula16ManipulaçãoDadosssssssssssssssssssssssssssss
PPTX
Aula 18 - Manipulacao De Arquivos python
PPTX
Curso de Java 9 - (Threads) Multitarefas.pptx
PPTX
Curso de Java 14 - (Explicações Adicionais (Classes Abstrata e Interface)).pptx
PPTX
Curso de Java 15 - (Uso de Servlets (Entendendo a Estrutura)).pptx
PDF
Processos na gestão de transportes, TM100 Col18
PDF
Apple Pippin Uma breve introdução. - David Glotz
PDF
Gestão de transportes básica no SAP S/4HANA, S4611 Col20
PPTX
Émile Durkheim slide elaborado muito bom
PPTX
Aula sobre banco de dados com firebase db
PPTX
Curso de Java 12 - (JDBC, Transation, Commit e Rollback).pptx
PPTX
Curso de Java 16 - (JEE (Utilizando o Padrão MVC)).pptx
PDF
Fundamentos de gerenciamento de ordens e planejamento no SAP TransportationMa...
PPTX
Curso de Java 10 - (IO Manipulação de Arquivos).pptx
PPTX
Curso de Java 11 - (Serializable (Serialização de Objetos)).pptx
PDF
Otimizador de planejamento e execução no SAP Transportation Management, TM120...
COBITxITIL-Entenda as diferença em uso governança TI
Programação - Linguagem C - Variáveis, Palavras Reservadas, tipos de dados, c...
Curso de Java 13 - (JavaEE (JSP e Servlets)).pptx
Mergulho profundo técnico para gestão de transportes no SAP S/4HANA, S4TM6 Col14
Aula16ManipulaçãoDadosssssssssssssssssssssssssssss
Aula 18 - Manipulacao De Arquivos python
Curso de Java 9 - (Threads) Multitarefas.pptx
Curso de Java 14 - (Explicações Adicionais (Classes Abstrata e Interface)).pptx
Curso de Java 15 - (Uso de Servlets (Entendendo a Estrutura)).pptx
Processos na gestão de transportes, TM100 Col18
Apple Pippin Uma breve introdução. - David Glotz
Gestão de transportes básica no SAP S/4HANA, S4611 Col20
Émile Durkheim slide elaborado muito bom
Aula sobre banco de dados com firebase db
Curso de Java 12 - (JDBC, Transation, Commit e Rollback).pptx
Curso de Java 16 - (JEE (Utilizando o Padrão MVC)).pptx
Fundamentos de gerenciamento de ordens e planejamento no SAP TransportationMa...
Curso de Java 10 - (IO Manipulação de Arquivos).pptx
Curso de Java 11 - (Serializable (Serialização de Objetos)).pptx
Otimizador de planejamento e execução no SAP Transportation Management, TM120...

Dsi 015 - poo e php - conexão com bancos de dados usando pdo

  • 1. Tecnologia em Sistemas para Internet Componente Curricular: Desenvolvimento para Servidores I 015 – Programação Orientada a Objetos e PHP Conexão com Bancos de Dados usando PDO – PHP Data Objects Professor: Jorge Luís Gregório | e-mail: jorge.gregorio@fatec.sp.gov.br @jlgregorio81 Jorge Luís Gregório
  • 2. Um pouco de história... • A comunidade PHP sempre foi muito grande e muito ativa no mundo todo, desta forma, o PHP cresceu com uma grande diversidade de bibliotecas construídas para resolver problemas muito específicos, principalmente quando o assunto é banco de dados. • Existem diversos SGBDs no mercado, entre eles, os mais populares são MySQL, Firebird, Postgres, entre outros. Desta forma, o PHP, no ápice do seu crescimento fornecia bibliotecas diferentes com funções diferentes para bancos de dados diferentes. • Apesar de resolver problemas de desenvolvedores de bancos de dados específicos, essa solução limitava o PHP, pois, ao ser considerada a mudança do SGBD de uma aplicação, o desenvolvedor teria que adaptar e/ou alterar todo a lógica de acesso ao banco de dados, pois o PHP fornecia funções específicas para cada banco. • Face a essa limitação, surge o PDO – PHP Data Objects
  • 3. PDO – PHP Data Objects • O PDO fornece uma API limpa e consistente que visa unificar a maioria das características e funções presentes nas extensões dos bancos de dados aos quais o PHP suporta (Dall’Oglio, 2009, pág. 159) • A PDO unifica as chamadas de métodos e, de acordo com o banco de dados selecionado, faz a delegação para a extensão específica do banco de dados. • A PDO é totalmente orientada a objetos, diferente das extensões específicas dos bancos de dados que ainda possui o modelo procedural de chamada de funções.
  • 4. PDO e as extensões para acesso a bancos de dados do PHP PDO Extensão do MySQL Extensão do PostgreSQL Extensão do SQLite Banco de dados Aplicação Web
  • 5. Ativando extensões no WAMP • Por padrão, a extensão para conexão com banco de dados MySQL vem ativa no Wamp. Caso deseja usar o Postgres, é necessário ativar a exetensão. – Clique no ícone do WAMP na bandeja do sistema, selecione a opção PHP, depos PHP Extensions e ative as opções php_pdo_pgsql e php_pgsql • Para fazer manualmente, é necessário abrir o arquivo php.ini na pasta do servidor Apache e retire o comentário (símbolo ;) das linhas onde se encontra digitado extension=php_pdo_pgsql.dll extension=php_pgsql
  • 6. Testando se o PDO/PGSQL está ativo • Depois de ativar as extensões do Postgres no PHP é necessário fazer um teste para verificar se estão ativas; • Crie um arquivo index.php e digite o seguinte código nele: phpinfo(); A função phpinfo mostrará todas as configurações do servidor Apache e quais drivers de conexão foram carregados. Localize as palavras PDO, pdo_pgsql e pgsql. Se todas estiverem presentes, tanto o driver de conexão com o Posgres quanto o PDO estão ativos.
  • 7. Verificando a configuração Abrindo o index.php no browser
  • 8. Erro persistente! • Caso os drivers/extensões não tenham sido carregados, provavelmente será necessário editar o arquivo de configuração do Apache inserindo uma linha de comando para carregar a DLL (Dynamic Link Library) de conexão com o Postgres. • Essa DLL fica na pasta do wamp no seguinte caminho: binphp<versão_do_php>libpq.dll Abra o arquivo de configuração do Apache (httpd.conf) que fica na pasta do wamp no seguinte caminho: binapache<versão_do_apacheconfhttpd.conf Logo após a última linha com o comando LoadModule, adicione a seguinte linha de comando: LoadFile “<raiz_do_wamp>/bin/php/<versão_do_php>/libpq.dll”
  • 9. Criando um banco de dados • Abra o PgAdmin (Postgres) e crie um banco de dados com o nome ‘database’ (sem aspas) • Clique no link para baixar o script para a criação das tabelas: – Clique aqui! Powered by:
  • 10. String de conexão Banco de Dados String de conexão FireBird new PDO(“firebird:dbname=C:base.GDB”, “SYSDBA”, “masterkey”); MySQL new PDO(‘mysql:unix_socket=/tmp/mysql.sock;host=loc alhost;port3306;dbname=livro’,’user’,’senha’) Postgres new PDO(‘pgsql:dbname=example;user=user;password=se nha;host=localhost); Adaptado de Dall’Oglio, 2009, pág. 160
  • 11. Criando uma classe de conexão namespace util; use PDO; /** * Description of Connection * * @author JorgeLuis */ class Connection { //..constantes para conexão com o Postgres const DBNAME = 'database'; const USER = 'postgres'; const PASSWORD='postdba'; const HOST = 'localhost'; const PORT = 5432; /** * Retorna um objeto do tipo PDO pronto para executar instruções SQL no banco de dados * @return PDO * @throws utilPDOException */ public static function getConnection(){ try { return new PDO("pgsql:dbname=".self::DBNAME.";user=".self::USER . ";password=".self::PASSWORD.";host=".self::HOST . ";port=".self::PORT); } catch (PDOException $ex) { throw $ex; } } }
  • 12. Inserindo dados O método exec da classe PDO é capaz de executar uma instrução SQL diretamente no banco de dados. O retorno do método é um número inteiro contendo a qtde de linhas linhas que foram atualizadas no banco de dados. require_once 'autoload.php'; use utilConnection; try { //..pega um objeto PDO $db = Connection::getConnection(); } catch (Exception $ex) { //..trata a exceção echo $ex->getMessage() . " - " . $ex->getCode(); } //..inserindo na tabela cidade $linhas = $db->exec("insert into cidade (nome, uf, cep) values('Urânia','SP','15760000')"); if ($linhas > 0) echo 'Dados inseridos!<br>'; else echo 'Erro!';
  • 13. Atualizando registros O comando exec pode ser usado também para comandos de update: require_once 'autoload.php'; use utilConnection; //..pega um objeto PDO $db = Connection::getConnection(); //..executa o comando update $linhas = $db->exec("update cidade set nome='Londrina', uf='PR' where id_cidade = 1"); if($linhas > 0) echo 'Dados atualizados com sucesso!<br>'; else echo 'Erro!<br>';
  • 14. Excluindo registros require_once 'autoload.php'; use utilConnection; //..pega um objeto PDO $db = Connection::getConnection(); //..executa o comando delete $linhas = $db->exec("delete from cidade where id_cidade = 1"); if($linhas > 0) echo 'Dados excluídos com sucesso!<br>'; else echo 'Erro!<br>';
  • 15. Listando registros • Para listar registros, isto é, executar uma consulta no banco de dados, o método query deverá ser invocado. Se não houver dados que satisfaçam a consulta, o retorno do método será false, caso contrário, será retornado um objeto PDOStatement que é um resultset no formato de um array composto de outros arrays. require_once 'autoload.php'; use utilConnection; //..pega um objeto PDO $db = Connection::getConnection(); //..executa a consulta $resultSet = $db->query('select * from cidade order by nome'); //..se houver resultSet, então itera-o mostrando os campos da consulta if($resultSet){ foreach ($resultSet as $reg) { echo $reg['id_cidade'] . ' - '; echo $reg['nome'] . ' - '; echo $reg['uf'] . ' - '; echo $reg['cep'] . '<br>'; } }
  • 16. Listando registros • É possível determinar outros formatos para retornar os dados usando a função FETCH e passando um parâmetro de acordo com a tabela: Parâmetros Descrição PDO::FETCH_ASSOC Retorna um array indexado pelo nome da coluna (padrão) PDO::FETCH_NUM Retorna um array indexado pela posição numérica da coluna PDO::FETCH_BOTH Retorna um array indexado pelo nome da coluna e pela posição numérica da mesma. PDO::FETCH_OBJ Retorna um objeto (StdClass), de modo que cada coluna é acessada como um propriedade. Adaptado de Dall’Oglio, 2009, pág. 162
  • 17. Listando registros - objetos require_once 'autoload.php'; use utilConnection; //..pega um objeto PDO $db = Connection::getConnection(); //..executa a consulta $resultSet = $db->query('select * from cidade order by nome'); if($resultSet){ while ($reg = $resultSet->fetch(PDO::FETCH_OBJ)){ echo $reg->id_cidade . ' - ' . $reg->nome . ' - ' . $reg->uf . ' - ' . $reg->cep . '<br>'; } }
  • 18. Listando registros – índice numérico require_once 'autoload.php'; use utilConnection; //..pega um objeto PDO $db = Connection::getConnection(); //..executa a consulta $resultSet = $db->query('select * from cidade order by nome'); if($resultSet){ while ($reg = $resultSet->fetch(PDO::FETCH_NUM)){ echo $reg[0] . ' - ' . $reg[1] . ' - ' . $reg[2] . ' - ' . $reg[3] . '<br>'; } } Este modo é recomendável para simplificar a referência aos atributos quando estes são conhecidos. O parâmetro PDO::BOTH permite que os atributos sejam referenciados tanto por índices numéricos, quanto por chaves.
  • 19. Tratamento de erros • A classe PDO possui um método chamado setAttribute ao qual é possível configurar, entre outros recursos avançados, o modo de como os erros gerados pelo objeto serão tratados. • É recomendável configurar a classe de conexão para gerar exceções, pois assim é possível lançar e/ou tratar os erros de forma mais elegante através dos já conhecidos blocos try..catch. • A exceção gerada é uma instância de PDOException, isto é, uma exceção específica para erros de bancos de dados. • Exemplo: //..pega um objeto PDO $db = Connection::getConnection(); //..seta o modo de erros $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); A partir de agora, o objeto $db irá lançar exceções, caso aconteçam.
  • 20. Exemplo completo try { //..pega um objeto PDO $db = Connection::getConnection(); //..seta o modo de erros $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //..executa a consulta - nome da tabela cidade está errado – vai gerar erro! $resultSet = $db->query('select * from cidades order by nome'); if ($resultSet) { while ($reg = $resultSet->fetch(PDO::FETCH_BOTH)) { echo $reg[0] . ' - ' . $reg[1] . ' - ' . $reg['uf'] . ' - ' . $reg['cep'] . '<br>'; } } } catch (PDOException $ex) { //..mostra a mensagem de erro echo $ex->getMessage(); }
  • 21. Modificando a classe Connection • Para fazer com que a classe Connection retorne um objeto PDO pronto a gerar exceções, segue uma nova proposta. namespace util; use PDO; /** * Description of Connection * * @author JorgeLuis */ class Connection { //..constantes para conexão com o Postgres const DBNAME = 'database'; const USER = 'postgres'; const PASSWORD='postdba'; const HOST = 'localhost'; const PORT = 5432; /** * Retorna um objeto do tipo PDO pronto para executar instruções SQL no banco de dados * @return PDO * @throws utilPDOException */ public static function getConnection(){ try { //..pega um objeto PDO $connection = new PDO("pgsql:dbname=".self::DBNAME.";user=".self::USER. ";password=".self::PASSWORD.";host=".self::HOST.";port=".self::PORT); //..configura para gerar exceções sempre que um erro ocorrer $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //..retorna o objeto PDO; return $connection; } catch (PDOException $ex) { throw $ex; } } }
  • 22. Exemplo de tratamento de erros require_once 'autoload.php'; use utilConnection; try { //..pega um objeto PDO $db = Connection::getConnection(); //..executa a consulta - nome da tabela cidade está errado – vai gerar Exceção $resultSet = $db->query('select * from cidades order by nome'); if ($resultSet) { while ($reg = $resultSet->fetch(PDO::FETCH_BOTH)) { echo $reg[0] . ' - ' . $reg[1] . ' - ' . $reg['uf'] . ' - ' . $reg['cep'] . '<br>'; } } } catch (PDOException $ex) { echo $ex->getMessage(); }
  • 23. Transações Uma transação representa uma interação entre a aplicação e o sistema de banco de dados tratada de forma única e independente. Pense em uma transação financeira de transferência de fundos. Este tipo de transação necessita de um grande cuidado pois, do contrário, uma conta pode ser debitada e a outra não ser creditada, ou vice-versa. Uma transação é uma sequência de trabalho que tem um ponto de início e de fim bem definidos [...]” DALL’OGLIO, 2009, pág. 206
  • 24. Propriedades de Transações - ACID • Atomicidade: uma transação pode envolver uma ou mais interações com o banco de dados, porém deve ser vista como uma única operação. Se uma delas falhar, os dados não refletirão o mundo real então, toda a operação deverá ser revertida (rollback). Executa tudo ou nada. Sem operações incompletas. • Consistêcia: após a transação, os dados devem permanecer íntegros, ou seja, com todas as suas restrições (chave primária, check, etc) intactas. • Isolamento: as transações devem ser executadas isoladas de outras transações, pois pode ser que um registro seja acessado por diversas transações ao mesmo tempo (venda de um produto). O resultado da transação só deve ser visível após o seu término. • Durabilidade: deve haver a garantia de que os dados serão persistentes após o término da transação, ou seja, ela não será desfeita e/ou perdida por qualquer que seja o motivo.
  • 25. Sintaxe try{ //..inicia a transação PDOObject->beginTransaction(); //..instrução SQL 01 //..instrução SQL 02 //..instrução SQL 03 //..instrução SQL n... //..confirma a transação PDOObject->commit(); } catch(PDOException $ex){ //..retorna ao estado inicial caso aconteça algum erro PDOObject->rollBack(); }
  • 26. Exemplo • No banco de dados, a tabela pessoafisica é uma especialização da tabela pessoa, ou seja, para cadastrar uma pessoa física é necessário primeiro a inserção dos dados na tabela pessoa e, após obter o nº do id inserido, é necessário inserir o registro específico na tabela pessoafisica. • Se qualquer uma das operações falhar no momento da confirmação (commit), o sistema deverá cancelar a transação (rollback). • Os dados deverão ser inseridos nas duas tabelas ou em nenhuma (atomicidade).
  • 27. Código-fonte comentado require_once 'autoload.php'; use utilConnection; try{ //..pega uma conexão $connection = Connection::getConnection(); //..inicia a transação $connection->beginTransaction(); //..inicia as operações da transação //..executa a instrução SQL para inserção em pessoa $connection->exec("insert into pessoa(nome, id_cidade) values ('Peter Parker', 2);"); echo 'Pessoa Inserida! <br>'; //..pega o id do registro inserido em pessoa para inserí-lo em pessoafisica $id = $connection->lastInsertId("seq_pessoa"); echo "ID inserido: $id <br>"; //..executa a instrução SQL para a inserção em pessoafisica $connection->exec("insert into pessoafisica values ($id, 'M', '111','222','Rua XYZ','15999000');"); echo 'Pessoa Física Inserida! <br>'; //..confirma a transação $connection->commit(); } catch (PDOException $ex){ //..Se gerar exceção, mostra o erro e executa um rollback. echo 'Erro na transação: ' . $ex->getMessage() . '<br>'; $connection->rollBack(); } Dica: Para verificar se o controle de transação está realmente dando certo, crie um erro em uma das instruções SQL, na primeira ou na segunda. Com erros, a lógica acima cairá no bloco catch e o rollback será executado desfazendo as alterações.
  • 28. Atividade Prática • Criar uma aplicação simples que cadastre e liste os dados de um formulário • Dados: – Nome (campo de texto) – Sexo (campo select) – Formação (campo select) • Ensino fundamental • Ensino médio • Superior • Pós graduação • Outros
  • 29. Mapeamento Objeto-Relacional • Persistência – Persistir quer dizer perdurar, resistir ao tempo. Em uma aplicação, persistir significa fazer com que os objetos do modelo de negócio sejam “gravados” em um local externo à aplicação e que, principalmente, permita sua posterior recuperação. – Objetos existem apenas durante um certo período de tempo dentro dos limites da aplicação, desta forma, é extremamente importante seu armazenamento.
  • 30. Mundo OO vs Mundo Relacional [...] existem diversos conceitos da orientação a objetos para os quais o modelo relacional simplesmente não oferece suporte, então temos uma diferença de conceito. Os bancos de dados foram construídos para armazenar dados, ao passo que, no paradigma orientado a objetos, além de dados (atributos), temos comportamento (métodos) e outras estruturas complexas. Dessa forma, é necessário utilizar alguma ferramenta de compatibilidade entre os dois modelos, que geralmente implementam algum técnica de mapeamento objeto-relacional. [...] DALL’OGLIO, 2009, pág. 222
  • 31. Mundo OO vs Mundo Relacional • Mundo Relacional – Tabelas: entidade que armazena dados – Registros: cada dado ou conjunto de dados de uma tabela real ou gerada por SQL – Chaves primárias: responsáveis por: • Fazer com que um registro seja único • Fazer com que as tabelas se relacionem através de ligação com chaves estrangeiras • Mundo OO – Objetos: armazenam dados e são capazes de realizar tarefas – Listas: conjuntos de objetos – Os relacionamentos são feitos por associações: • Associação simples • Composição • Agregação
  • 32. Mundo OO vs Mundo Relacional • Padrões para mapeamento objeto-relacional: – Identity Field: campo autoincremento para chave primária/estrangeira – Foreign Key Mapping: composição (relacionamento “forte” todo/parte) no mundo OO pode ser realizada através de chaves estrangeiras. – Association Table Mapping: agregação (relacionamento “fraco” todo/parte ) também pode ser mapeado como chaves estrangeiras. – Herança • Single Table Inheritance: as classes são mapeadas para uma única tabela contendo todos os atributos comuns da hierarquia. • Concrete Table Inheritance: as classes são mapeadas para diversas tabelas, cada classe possui uma tabela de forma independente. • Class Table Inheritance: e criada uma tabela para cada classe na estrutura da hierarquia. Após isso, cria-se uma generalização/especialização através de pares de chaves primárias. Maiores detalhes em Dall’Oglio, pág. 222-231.
  • 33. DAO – Data Access Object • O padrão de projeto DAO propõe a criação de uma camada de acesso a dados independente de outras camadas da aplicação, ou seja, os objetos DAO possui a responsabilidade de persistir objetos em bancos de dados, realizando, o mapeamento objeto-relacional (Object-Relational Mapping). • Além da persistência (inserts e updates), os objetos DAO também podem recuperar dados através de consultas SQL e retornar apenas objetos de negócio (model) para a aplicação. • Vantagens: – Isolar a lógica de acesso e manipulação de dados de outros componentes do sistema melhora a reusabilidade, escalabidade e manutenabilidade do código.
  • 34. DAO – Data Access Object model Classe1 Classe2 * * Classe3 Classe4 1 * +findById() +persist() +query() +delete() DAO Banco de dados Objetos model Instruções SQL Dados Objetos
  • 35. Exemplo • Baixar o código-fonte comentado no link abaixo: – Clique aqui! Powered by:
  • 36. Discussão – a camada model
  • 37. Discussão – a camada dao
  • 38. Discussão – métodos DAO • Os objetos DAO devem implementar a interface Idao, então, surgem os seguintes métodos: – persist($modelObject) • Insere e/ou atualiza um registro no banco de dados mediante um objeto model informado. O objeto deverá ser mapeado em dados relacionais e persistido no Banco de Dados. – delete($id) • Exclui um registro baseado no id informado – query($field = null, $like=null) • Realiza uma query do tipo “selecionar tudo” ou usando um campo e uma cláusula ‘like’ como filtros. Retorna um ArrayObject (array de objetos) – findById($id) • Recupera um registro mediante o id informado, mapeia-o em objeto e retorna para a aplicação.
  • 39. O que vem depois??? • Agora que a camada DAO está pronta, é necessário integrá-la a sua aplicação. • MVC – Model/View/Controller – Padrão de Projeto (Design Pattern) que divide uma aplicação em 3 camadas distintas. – O padrão DAO combina muito bem com o MVC.
  • 40. Bibliografia recomendada DALL’OGLIO, Pablo. Capítulo 3: Manipulação de dados. In: ________. PHP: programando com orientação a objetos. 2. ed. São Paulo: Novatec, 2009. p. 154-220. Manual do PHP. PHP Data Objects. Disponível em <http://php.net/manual/pt_BR/ book.pdo.php> Acesso em 20 jan. 2015. Manual do PHP. PHP::setAttribute. Disponível em <http://php.net/manual/pt_BR/ pdo.setattribute.php> Acesso em 20 jan. 2015.