SlideShare uma empresa Scribd logo
1 de 104
Baixar para ler offline
Flávio Lisboa - PHP Conference 2010
Mapeamento Objeto Relacional com PHP
Flávio Gomes da Silva Lisboa
@fgsl
www.fgsl.eti.br
@fgsl
A reprodução é livre, apenas cite a fonte
Flávio Lisboa - PHP Conference 2010
Quem sou eu
2007
2008 2009
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
►Problemas
►Soluções
►Opções:
Mapeamento Objeto Relacional
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Problemas
A maioria das aplicações Web persistem dados
em um banco de dados.
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Problemas
O processo de desenvolvimento utiliza conexões
diferentes (desenvolvimento, teste, homologação
e produção).
Adaptado de sofist.com.br
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Problemas
Uma aplicação pode utilizar-se de várias fontes
de dados diferentes ao mesmo tempo.
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Problemas
E ela também pode ser distribuída para trabalhar
com bases de dados que tem a mesma estrutura,
mas são fornecidas por fabricantes diferentes, por
exemplo, MySQL e PostgreSQL.
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Problemas
Por isso, código específico para manipular um
determinado mecanismo de persistência e
recuperação de dados não deve ficar espalhado
pela aplicação.
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Problemas
Além disso, o banco de dados deve ficar
desacoplado da aplicação, para que mudanças
no banco (como alterações em nomes de campos
de tabelas) não gerem trabalho de recodificação.
infoescola.com
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
Mapear dados de objetos para bancos de dados relacionais
Referência:
Padrões de Arquitetura
de Aplicações Corporativas
Martin Fowler,
arquiteto de software
e
consultor
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Momento Cultural
O que é um arquiteto de software?
A reprodução é livre, apenas cite a fonte
Flávio Lisboa - PHP Conference 2010
Momento Cultural
E o que é um consultor?
* to con: enganar
* demeaning: degradante
Dilbert, by Scott Adams
A reprodução é livre, apenas cite a fonte
Flávio Lisboa - PHP Conference 2010
Momento Cultural
E o que é um consultor?
A reprodução é livre, apenas cite a fonte
Flávio Lisboa - PHP Conference 2010
Momento Cultural
E o que é um consultor?
Dilbert, by Scott Adams
A reprodução é livre, apenas cite a fonte
Flávio Lisboa - PHP Conference 2010
Soluções
Embora existam várias técnicas
para embutir SQL em uma
linguagem de programação,
elas são todas um pouco
deselegantes.
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
Seria melhor acessar os dados
usando mecanismos que se
encaixem com a linguagem de
desenvolvimento da aplicação.
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
Por essas razões, é sábio
separar o acesso SQL da lógica
de domínio e colocá-las em
classes separadas.
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
Padrões de Projeto: soluções reutilizáveis de
software orientado a objetos
The Greatest American Hero, by Stephen J. Cannell, starring William Kat
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
Padrões de Projeto: soluções reutilizáveis de
software orientado a objetos
Abin Sur, Hal Jordan, Green Lanterns created by John Broome and Gil Kane
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
Padrão Básico
Gateway
Um objeto que encapsula o acesso a um sistema
ou recurso externo
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
Gateway
API simples para lidar de forma orientada a
objetos com coisas que não são objetos
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
Padrões de Mapeamento Objeto Relacional
Row Data Gateway
Um objeto para cada linha retornada por uma
consulta
Utilidade: trabalhar com um registro específico
Table Data Gateway
Um objeto para cada tabela
Utilidade: trabalhar com um conjunto de registros
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
Padrões de Mapeamento Objeto Relacional
Active Record
Um objeto de domínio cliente sabe como interagir
com tabelas do banco de dados
Data Mapper
Isola os objetos do domínio do banco de dados
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
Diferenças
Active Record
O objeto de domínio sabe como incluir, alterar,
excluir e pesquisar.
Data Mapper
O objeto de domínio invoca um objeto que sabe
como incluir, alterar, excluir e pesquisar.
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
Preciso
implementar
tudo isso?
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Soluções
A reprodução é livre, apenas cite a fonte
@fgsl
Use um framework ORM
framework... ...abstração que une códigos
comuns entre vários projetos de software
provendo uma funcionalidade genérica...
Fonte: http://pt.wikipedia.org/wiki/Framework
Aplicações
Camada de ModeloCamada de Modelo
Objeto de domínio
Framework ORM
Flávio Lisboa - PHP Conference 2010
Opções
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Opções
A reprodução é livre, apenas cite a fonte
@fgsl
Estudo de caso:
cadastro de livros e categorias de livros
Flávio Lisboa - PHP Conference 2010
Opções
A reprodução é livre, apenas cite a fonte
@fgsl
Estudo de caso:
cadastro de livros e categorias de livros
CREATE TABLE `livrosdb`.`livros` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`titulo` VARCHAR( 80 ) NOT NULL ,
`id_categoria` INT UNSIGNED NOT NULL ,
PRIMARY KEY ( `id` ) ,
INDEX ( `titulo` , `id_categoria` ) ) ENGINE = InnoDB
CREATE DATABASE `livrosdb` ;
CREATE TABLE `livrosdb`.`categorias` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`nome` VARCHAR( 80 ) NOT NULL ,
PRIMARY KEY ( `id` ) ,
INDEX ( `nome` ) ) ENGINE = InnoDB
Flávio Lisboa - PHP Conference 2010
Opções
A reprodução é livre, apenas cite a fonte
@fgsl
Projeto PHP com três implementações:
propel
doctrine
zenddb
exemploormphp
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
http://www.propelorm.org
Pode ser instalado pelo Depende de
PHing Is Not GNU make
baseado em
que também pode instalar
►Versão 1.5.2 requer PHP 5.2.4
►Usa PDO
►É usado pelo
http://www.phing.info
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Possui dois componentes:
Um gerador de modelos: não obrigatório.
(mas se não usar vai ficar muito difícil...)
propel-1.5.2/generator/bin/propel-gen (Linux)
propel-1.5.2/generator/bin/propel-gen.bat (Windows)
Uma biblioteca de classes: necessária
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Neste caso, foram instalados manualmente o
propel 1.5.2 e o phing 2.4.2 no Linux.
Foram criados links simbólicos para os scripts do
Propel e do Phing no diretório /usr/bin. O script
do Phing precisa de permissão de execução para
ser chamado pelo Propel.
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Diretiva Valor
ze1_compatibility_mode Off
magic_quotes_gpc Off
magic_quotes_sybase Off
Configuração do php.ini
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
schema.xml (raiz do projeto)
<?xml version="1.0" encoding="UTF-8"?>
<database name="livrosdb" defaultIdMethod="native">
<table name="livros" phpName="Livro">
<column name="id" type="integer" required="true" primaryKey="true"
autoIncrement="true" />
<column name="titulo" type="varchar" size="80" required="true" />
<column name="id_categoria" type="integer" required="true" />
<foreign-key foreignTable="categorias">
<reference local="id_categoria" foreign="id" />
</foreign-key>
</table>
<table name="categorias" phpName="Categoria">
<column name="id" type="integer" required="true" primaryKey="true"
autoIncrement="true" />
<column name="nome" type="varchar" size="80" required="true" />
</table>
</database>
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
build.properties (raiz do projeto)
# Database driver
propel.database = mysql
# Project name
propel.project = propel
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Entre no diretório do projeto e execute o
comando:
propel-gen om
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
[propel-om] Processing: schema.xml
[propel-om] Processing Datamodel : schema.xml
[propel-om] - processing database : livrosdb
[propel-om] + livros
[propel-om] -> BaseLivroPeer [builder: PHP5PeerBuilder]
[propel-om] -> BaseLivro [builder: PHP5ObjectBuilder]
[propel-om] -> LivroTableMap [builder: PHP5TableMapBuilder]
[propel-om] -> BaseLivroQuery [builder: QueryBuilder]
[propel-om] -> LivroPeer [builder: PHP5ExtensionPeerBuilder]
[propel-om] -> Livro [builder: PHP5ExtensionObjectBuilder]
[propel-om] -> LivroQuery [builder: ExtensionQueryBuilder]
[propel-om] + categorias
[propel-om] -> BaseCategoriaPeer [builder: PHP5PeerBuilder]
[propel-om] -> BaseCategoria [builder: PHP5ObjectBuilder]
[propel-om] -> CategoriaTableMap [builder: PHP5TableMapBuilder]
[propel-om] -> BaseCategoriaQuery [builder: QueryBuilder]
[propel-om] -> CategoriaPeer [builder: PHP5ExtensionPeerBuilder]
[propel-om] -> Categoria [builder: PHP5ExtensionObjectBuilder]
[propel-om] -> CategoriaQuery [builder: ExtensionQueryBuilder]
[propel-om] Object model generation complete - 14 files written
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Pra cada tabela, Propel cria 3 arquivos
(que você vai utilizar diretamente):
Uma classe modelo que representa uma linha
no banco de dados;
Uma classe peer com constantes estáticas e
métodos para compatibilidade com versões
anteriores de Propel;
Uma classe query, para operar sobre a tabela
para recuperar e atualizar registros
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Propel pode gerar o script SQL das tabelas com o
comando:
propel-gen sql
O script é gravado no arquivo
build/sql/schema.sql
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Propel também pode criar as tabelas no banco,
configurando a conexão no build.properties.
propel.database.url = [DSN padrão PDO]
propel.database.user =
propel.database.password =
propel-gen sql
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
É preciso criar o arquivo runtime-conf.xml na
raiz do projeto, com as conexões a serem usadas
em tempo de execução
<?xml version="1.0" encoding="UTF-8"?>
<config>
<propel>
<datasources default="livrosdb">
<datasource id="livrosdb">
<adapter>mysql</adapter> <!-- sqlite, mysql, myssql, oracle, or
pgsql -->
<connection>
<dsn>mysql:host=localhost;dbname=livrosdb</dsn>
<user>root</user>
<password>admin</password>
</connection>
</datasource>
</datasources>
</propel>
</config>
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Por questão de performance (tempo de parsing
do XML), Propel usa uma versão PHP do arquivo
runtime-conf.xml.
Essa versão é gerada com o comando:
propel-gen convert-conf
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Para usar o Propel na aplicação, você precisa:
1)Adicionar o diretório runtime/lib do Propel no include_path do
PHP
2)Importar o arquivo Propel.php
3)Carregar a configuração das conexões
4)Adicionar o diretório build/classes da aplicação no include_path
do PHP
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Algo assim:
<?php
define(BASE_PATH,
substr(realpath(__FILE__),0,strpos(realpath(__FILE__),'exemploormphp')));
define(APPLICATION, 'exemploormphp/propel');
set_include_path(get_include_path() . PATH_SEPARATOR . BASE_PATH.'propel-
1.5.2/runtime/lib');
// Inclui o script principal do Propel
require_once 'Propel.php';
// Inicia a configuração de tempo de execução
Propel::init(BASE_PATH.APPLICATION.'/build/conf/propel-conf.php');
// Adiciona o diretório 'classes' ao include path
set_include_path(BASE_PATH.APPLICATION.'/build/classes' . PATH_SEPARATOR .
get_include_path());
exemploormphp/propel/init.php
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de inclusão
exemploormphp/propel/create.php
require_once 'init.php';
$nome = (string) $_GET['nome'];
$categoria = new Categoria();
$categoria->setNome($nome);
$categoria->save();
unset($categoria);
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de consulta
exemploormphp/propel/recover.php
require_once 'init.php';
$id = (int) $_GET['id'];
$nome = (string) $_GET['nome'];
if (!empty($id))
$categoria = CategoriaQuery::create()->findPk($id);
if (!empty($nome))
$categoria = CategoriaQuery::create()->findOneByNome($nome);
echo 'Nome: ' . $categoria->getNome();
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de alteração
exemploormphp/propel/update.php
require_once 'init.php';
$id = (int) $_GET['id'];
$nome = (string) $_GET['nome'];
if (!empty($id))
$categoria = CategoriaQuery::create()->findPk($id);
if (!empty($nome))
$categoria = CategoriaQuery::create()->findOneByNome($nome);
$categoria->setNome('Huguinho');
$categoria->save();
$id = $categoria->getId();
unset($categoria);
$categoria = CategoriaQuery::create()->findPk($id);
echo 'Nome: ' . $categoria->getNome();
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de exclusão
exemploormphp/propel/delete.php
require_once 'init.php';
$id = (int) $_GET['id'];
$nome = (string) $_GET['nome'];
if (!empty($id))
$categoria = CategoriaQuery::create()->findPk($id);
if (!empty($nome))
$categoria = CategoriaQuery::create()->findOneByNome($nome);
print_r($categoria);
$categoria->delete();
print_r($categoria);
O objeto ainda existe, mas não
é mais persistente. O estado pode ser
verificado com o método isDeleted().
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de consulta a vários registros
exemploormphp/propel/listing.php
require_once 'init.php';
$categoria = CategoriaQuery::create()-
>findOneByNome('suspense');
$livros = LivroQuery::create()-
>filterByCategoria($categoria)->orderByTitulo()->find();
foreach($livros as $livro)
{
print_r($livro);
}
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de consulta SQL customizada
exemploormphp/propel/sqlisting.php
require_once 'init.php';
$con = Propel::getConnection(LivroPeer::DATABASE_NAME);
$sql = 'SELECT l.id, l.titulo,c.nome ';
$sql .= 'FROM livros as l INNER JOIN categorias as c ';
$sql .= 'ON l.id_categoria = c.id ';
$sql .= 'WHERE c.nome = :name';
$stmt = $con->prepare($sql);
$stmt->execute(array(':name' => 'suspense'));
$formatter = new PropelObjectFormatter();
$formatter->setClass('Livro');
$formatter->setPeer('LivroPeer');
$livros = $formatter->format($stmt);
foreach($livros as $livro)
{
print_r($livro);
}
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de efeito de relacionamento
exemploormphp/propel/relation.php
require_once 'init.php';
$categoria = new Categoria();
$categoria->setNome('suspense');
$livro = new Livro();
$livro->setTitulo('A volta dos que não foram');
$livro->setCategoria($categoria);
$livro->save();
unset($livro);
$livro = LivroQuery::create()->filterByCategoria($categoria)-
>findOne();
echo 'Título: ' . $livro->getTitulo().'<br/>';
echo 'Categoria: ' . $livro->getCategoria()->getNome();
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Transações
$con = Propel::getConnection(CategoriaPeer::DATABASE_NAME);
$con->beginTransaction();
Try {
O QUE VOCÊ ESPERA QUE OCORRA
$con->commit();
} catch (Exception $e) {
O QUE OCORRE
$con->rollback();
throw $e;
}
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Ganchos
Class Livro extends BaseLivro
public function postSave(PropelPDO $con)
{
...
}
public function postDelete(PropelPDO $con)
{
...
}
public function updateCategoria(PropelPDO $con)
{
...
}
}
Flávio Lisboa - PHP Conference 2010
Propel
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
http://www.doctrine-project.org
Mapeador
Objeto
Relacional
Camada de Abstração
de Banco de Dados
ORM DBAL
usa
►Versão 1.2.3 requer PHP 5.2.3
►Usa PDO
►Versão 2.0 usa PHP 5.3 e é...
TOTALMENTE DIFERENTE!
Pode ser instalado pelo
MongoDB
ODM
Migrations Common
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Neste caso, foi instalado manualmente o Doctrine
1.2.3 no Linux.
Foi criado um diretório lib/vendor/doctrine no
projeto, com links simbólicos para o diretório
Doctrine e para o arquivo Doctrine.php.
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Inicialização do Doctrine:
exemploormphp/doctrine/init.php
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) .
'/lib/vendor/doctrine');
require_once('Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));
spl_autoload_register(array('Doctrine', 'modelsAutoload'));
$manager = Doctrine_Manager::getInstance();
$dsn = 'mysql:dbname=livrosdb;host=127.0.0.1';
$user = 'root';
$password = 'admin';
$dbh = new PDO($dsn,$user,$password);
$conn = $manager->connection($dbh,'livrosdb');
Doctrine_Core::loadModels(array('models','models/generated'));
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Doctrine possuía uma ferramenta de linha de
comando, com geração de código, similar ao
Propel. Essa ferramenta estava disponível na
distribuição Sandbox.
Só que a Sandbox não
está mais disponível...
Na versão 2.0, a linha de comando já vem
incluída no ORM padrão. Mas aqui não estamos
falando da versão 2.0...
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Mas isso não
significa que não
dê pra gerar os
modelos!
Duffy Duck by Warner Bros
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Crie no projeto uma pasta chamada models.
Crie na raiz do projeto um script que invoque o
método generateModelsFromDb da classe
Doctrine_Core:
require_once 'init.php';
Doctrine_Core::generateModelsFromDb('models',
array('livrosdb'),
array('generateTableClasses' => true));
exempoormphp/doctrine/gom.php
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
São geradas três classes
para cada tabela...
As classes com prefixo
Base contém a definição
da tabela e são herdadas
pela classe que
implementa ActiveRecord.
A classe com sufixo Table
é um Data Mapper.
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Para não gerar os Data Mappers, a chave
generateTableClasses do método
generateModelsFromDb deve ser configurada
para false.
Você pode
apagar os
arquivos
também, se
quiser.
Dee Dee & Dexter by Hanna Barbera
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Mas é preciso verificar os relacionamentos
gerados. No nosso exemplo, o Doctrine gera um
relacionamentos um-pra-muitos entre Livros e
Categorias, sendo que na verdade é um-pra-um.
class Livros extends BaseLivros
{
public function setUp()
{
parent::setUp();
$this->hasOne('Categorias', array(
'local' => 'id_categoria',
'foreign' => 'id'
)
);
}
}
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Também é possível criar scripts com as
definições das tabelas com o Doctrine DBAL.
Esses scripts podem ter a conexão
parametrizada, de forma a gerar tabelas para
qualquer banco de dados.
Também é possivel criar definições de tabelas no
formato YAML (Yaml Ain't Markup Language),
criar os modelos a partir delas e aí gerar as
tabelas.
DBAL
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de inclusão
exemploormphp/doctrine/create.php
require_once 'init.php';
$nome = (string)
$_GET['nome'];
$categoria = new Categorias();
$categoria->nome = $nome;
$categoria->save();
unset($categoria);
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de consulta
exemploormphp/doctrine/recover.php
require_once 'init.php';
$id = (int) $_GET['id'];
$nome = (string) $_GET['nome'];
$categoriaTable = CategoriasTable::getInstance();
if (!empty($id))
$categoria = $categoriaTable->findOneById($id);
if (!empty($nome))
$categoria = $categoriaTable->findOneByNome($nome);
echo 'Nome: ' . $categoria->nome;
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de alteração
exemploormphp/doctrine/update.php
require_once 'init.php';
$id = (int) $_GET['id'];
$nome = (string) $_GET['nome'];
if (!empty($id))
$categoria = CategoriasTable::getInstance()->find($id);
if (!empty($nome))
$categoria = CategoriasTable::getInstance()->findOneByNome($nome);
$categoria->nome = 'Huguinho';
$categoria->save();
$id = $categoria->id;
unset($categoria);
$categoria = CategoriasTable::getInstance()->find($id);
echo 'Nome: ' . $categoria->nome;
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de exclusão
exemploormphp/doctrine/delete.php
require_once 'init.php';
$id = (int) $_GET['id'];
$nome = (string) $_GET['nome'];
if (!empty($id))
$categoria = CategoriasTable::getInstance()->find($id);
if (!empty($nome))
$categoria = CategoriasTable::getInstance()-
>findOneByNome($nome);
print_r($categoria);
$categoria->delete();
print_r($categoria);
O objeto ainda existe, mas não
é mais persistente. O estado pode ser
verificado com o método state().
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de consulta a vários registros
exemploormphp/doctrine/listing.php
require_once 'init.php';
$livros = LivrosTable::getInstance()-
>findByDql('Categorias.nome = ?','romance');
echo 'Quantidade de livros: ' . count($livros);
foreach($livros as $livro)
{
print_r($livro);
}
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de consulta SQL customizada
exemploormphp/doctrine/sqlisting.php
require_once 'init.php';
$q = Doctrine_Query::create($conn)
->select('l.id, l.titulo, c.nome')
->from('Livros l')
->innerJoin('l.Categorias c')
->where('c.nome = ?');
$livros = $q->execute(array('romance'));
echo 'Quantidade de livros: ' .
count($livros);
foreach($livros as $livro)
{
print_r($livro);
}
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de efeito de relacionamento
exemploormphp/doctrine/relation.php
require_once 'init.php';
$categoria = new Categorias();
$categoria->nome = 'romance';
$livro = new Livros();
$livro->titulo = 'Poeira em alto mar';
$livro->Categorias = $categoria;
$livro->save();
unset($livro);
$livro = LivrosTable::getInstance()-
>findByDql('Categorias.nome = ?','romance')->get(0);
echo 'Título: ' . $livro->titulo . '<br/>';
echo 'Categoria: ' . $livro->Categorias->nome;
Flávio Lisboa - PHP Conference 2010
$conn = beginTransaction();
Try {
O QUE VOCÊ ESPERA QUE OCORRA
$conn->commit();
} catch (Exception $e) {
O QUE OCORRE
$conn->rollback();
throw $e;
}
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Transações
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Ganchos
Class Livros extends BaseLivros
public function preSave($event)
{
...
}
public function postSave($event)
{
...
}
public function postDqlSelect($event)
{
...
}
}
Flávio Lisboa - PHP Conference 2010
Doctrine
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
►Versão 1.10 requer PHP 5.2.4
►Usa PDO
►Versão 2.0 usará PHP 5.3 e terá ...
MUITA COISA LEGAL!
Pode ser instalado pelo
...mas por um canal não oficial Zend_Db_Adapter
Zend_Db_Profiler
Zend_Db_Select
Zend_Db_Statement
Zend_Db_Table
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Neste caso, foi instalado manualmente o Zend
Framework 1.10.6. Na raiz do projeto foi criado
um link simbólico para o diretório
ZendFramework-1.10.6/library/Zend.
Na raiz do projeto foi criada uma pasta models
para armazenar os modelos.
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
require_once 'Zend/Loader/Autoloader.php';
set_include_path(get_include_path() . PATH_SEPARATOR .
dirname(__FILE__) . '/models');
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('Zend_Config_*');
$autoloader->registerNamespace('Zend_Db_*');
$config = new Zend_Config_Ini('config.ini','database');
$conn = Zend_Db::factory($config->db->adapter,$config->db-
>params->toArray());
exemploormphp/zenddb/init.php
Inicialização do Zend_Db:
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
exemploormphp/zenddb/config.ini
Configuração da conexão:
[database]
db.adapter = PDO_MYSQL
db.params.username = root
db.params.password = admin
db.params.dbname = livrosdb
db.params.host = localhost
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Zend Framework possui um componente
chamado Zend_Tool, que é uma ferramenta de
linha de comando para geração de código.
Zend_Tool cria as classes de modelo, mas
somente quando o projeto foi criado com a
estrutura do Zend_Framework, porque as
definições são lidas e gravadas no arquivo
.zfproject.xml.
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Por outro lado, você não precisa
necessariamente criar a classe de modelo para
manipular o banco porque o Zend_Db provê uma
implementação genérica de Data Mapper.
Basta instanciar Zend_Db_Table passando para o
construtor o nome da tabela no banco de dados.
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de inclusão com Data Mapper:
exemploormphp/zenddb/createwithoutmodel.php
require_once 'init.php';
$categoria = new Zend_Db_Table('categorias');
$categoria->insert(array('nome'=>'infantil'));
unset($categoria);
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Mas a criação do modelo é fácil:
exemploormphp/zenddb/models/Categoria.php
class Categoria extends Zend_Db_Table_Abstract
{
protected $_name = 'categorias';
}
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de inclusão com modelo definido:
exemploormphp/zenddb/create.php
require_once 'init.php';
Zend_Loader::loadClass('Categoria');
$dm = new Categoria();
$categoria = $dm->createRow();
$categoria->nome = 'infantil';
$categoria->save();
unset($categoria);
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de consulta
exemploormphp/zenddb/recover.php
require_once 'init.php';
$id = (int) $_GET['id'];
$nome = (string) $_GET['nome'];
Zend_Loader::loadClass('Categoria');
$dm = new Categoria();
if (!empty($id))
$categoria = $dm->find($id)->current();
if (!empty($nome))
$categoria = $dm->fetchRow($dm->getDefaultAdapter()->quoteInto('nome = ?',
$nome));
echo 'Nome: ' . $categoria->nome;
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de alteração
exemploormphp/zenddb/update.php
require_once 'init.php';
$id = (int) $_GET['id']; $nome = (string) $_GET['nome'];
Zend_Loader::loadClass('Categoria');$dm = new Categoria();
if (!empty($id))
$categoria = $dm->find($id)->current();
if (!empty($nome))
$categoria = $dm->fetchRow($dm->getDefaultAdapter()->quoteInto('nome = ?',$nome));
$categoria->nome = 'Huguinho';
$categoria->save();
$id = $categoria->id;
unset($categoria);
$categoria = $dm->find($id)->current();
echo 'Nome: ' . $categoria->nome;
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de exclusão
exemploormphp/zenddb/delete.php
require_once 'init.php';
$id = (int) $_GET['id'];
$nome = (string) $_GET['nome'];
Zend_Loader::loadClass('Categoria');
$dm = new Categoria();
if (!empty($id))
$categoria = $dm->find($id)->current();
if (!empty($nome))
$categoria = $dm->fetchRow($dm->getDefaultAdapter()->quoteInto('nome = ?',
$nome));
print_r($categoria->id);
$categoria->delete();
print_r($categoria->id);
O objeto ainda existe, mas seus atributos
estão vazios.
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Relacionamento no Modelo
exemploormphp/zenddb/models/Livro.php
class Livro extends Zend_Db_Table_Abstract
{
protected $_name = 'livros';
protected $_referenceMap = array(
'Categoria' => array(
'columns' => 'id_categoria',
'refTableClass' => 'Categoria',
'refColumns' => 'id'
));
}
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de consulta a vários registros
exemploormphp/zenddb/listing.php
require_once 'init.php';
Zend_Loader::loadClass('Categoria');
$dm = new Categoria();
$categoria = $dm->fetchRow($dm->getDefaultAdapter()-
>quoteInto('nome = ?','infantil'));
$livros = $categoria->findDependentRowset('Livro');
echo 'Quantidade de livros: ' . count($livros);
foreach($livros as $livro)
{
print_r($livro);
}
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de consulta SQL customizada
exemploormphp/zenddb/sqlisting.php
require_once 'init.php';
Zend_Loader::loadClass('Livro');
$dm = new Livro();
$select = $dm->select(Zend_Db_Table::SELECT_WITH_FROM_PART)
->setIntegrityCheck(false);
$select->join('categorias','livros.id_categoria = categorias.id')
->where('categorias.nome = ?','infantil');
$livros = $dm->fetchAll($select);
echo 'Quantidade de livros: ' . count($livros);
foreach($livros as $livro)
{
print_r($livro);
}
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Exemplo de efeito de relacionamento
exemploormphp/zenddb/relation.php
require_once 'init.php';
Zend_Loader::loadClass('Livro');Zend_Loader::loadClass('Categoria');
Zend_Loader::loadClass('LivroRow');
$dmc = new Categoria();
$categoria = $dmc->createRow();
$categoria->nome = 'tragédia';
$dml = new Livro(array('rowClass' => 'LivroRow'));
$livro = $dml->createRow();
$livro->titulo = 'Afoguei meu peixinho dourado';
$livro->setCategoria($categoria);
$livro->save(); $livro->refresh();
$id = $livro->id; unset($livro);
$livro = $dml->find($id)->current();
echo 'Título: ' . $livro->titulo . '<br/>';
echo 'Categoria: ' . $livro->findParentRow('Categoria')->nome;
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Atualização automática de registro relacionado
exemploormphp/zenddb/models/LivroRow.php
class LivroRow extends Zend_Db_Table_Row_Abstract
{
private $_categoria;
public function setCategoria($categoria)
{
$this->_categoria = $categoria;
}
public function save()
{
$this->_categoria->save();
$this->id_categoria = $this->_categoria->id;
parent::save();
}
}
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Este é um projeto GPLv2, que já faz de forma transparente o que
foi feito usando a extensão de Zend_Db_Table_Row_Abstract. Ele
vem pronto para trabalhar com MySQL, mas por herança é
possível criar adaptadores para outros bancos.
Há uma proposta em construção, para criar uma nova
implementação de ActiveRecord no Zend Framework:
http://code.google.com/p/zend-framework-orm
http://framework.zend.com/wiki/display/ZFPROP/Zend_Db_ActiveRecord
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Transações
$conn = Zend_Db_Table_Abstract::getDefaultAdapter();
$conn->beginTransaction();
Try {
O QUE VOCÊ ESPERA QUE OCORRA
$conn->commit();
} catch (Exception $e) {
O QUE OCORRE
$conn->rollback();
throw $e;
}
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Ganchos
Class LivroRow extends Zend_Db_Table_Row_Abstract
protected function _insert()
{
...
}
protected function _postInsert()
{
...
}
protected function _update()
{
...
}
}
Flávio Lisboa - PHP Conference 2010
Zend_Db
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
E agora, o que eu faço?
A reprodução é livre, apenas cite a fonte
@fgsl
Flávio Lisboa - PHP Conference 2010
Sei lá, entende?
A reprodução é livre, apenas cite a fonte
@fgsl
Patropi, interpretado por Orival Pessini
Flávio Lisboa - PHP Conference 2010 A reprodução é livre, apenas cite a fonte
@fgsl
Bill Karwin
Mas como com qualquer
ORM, há, inevitavelmente,
algumas consultas SQL e
operações que você não pode
fazer através da interface OO.
Nenhum ORM pode servir
como um shopping que tem
apenas uma loja.
Flávio Lisboa - PHP Conference 2010 A reprodução é livre, apenas cite a fonte
@fgsl
Independente de sua
escolha, saiba que
Zend Framework
trabalha com todos!
Wheelie and The Chopper Bunch (NBC,1974)
Flávio Lisboa - PHP Conference 2010
Coisas Realmente Importantes
A reprodução é livre, apenas cite a fonte
@fgsl
Flexibilidade
Flávio Lisboa - PHP Conference 2010
Coisas Realmente Importantes
A reprodução é livre, apenas cite a fonte
@fgsl
Facilidade de Manutenção
Kombi, Volkswagen
Flávio Lisboa - PHP Conference 2010
Obrigado!
A reprodução é livre, apenas cite a fonte
@fgsl
www.fgsl.eti.br
Little Einsteins by Walt Disney

Mais conteúdo relacionado

Mais procurados

PHP e MySQL para iniciantes
PHP e MySQL para iniciantesPHP e MySQL para iniciantes
PHP e MySQL para iniciantesEduardo Mendes
 
Doctrine 2 camada de persistência para php
Doctrine 2   camada de persistência para phpDoctrine 2   camada de persistência para php
Doctrine 2 camada de persistência para phpFabio B. Silva
 
Abstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineAbstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineOtávio Calaça Xavier
 
PHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta PerformancePHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta PerformanceFelipe Ribeiro
 
Aula 5 PHP - Criação de sites II
Aula 5 PHP - Criação de sites IIAula 5 PHP - Criação de sites II
Aula 5 PHP - Criação de sites IIinfo_cimol
 
Apresentação palestra ireport
Apresentação palestra ireportApresentação palestra ireport
Apresentação palestra ireportfpsgyn
 
PHP Experience 2016 - [Palestra] Keynote: PHP-7
PHP Experience 2016 - [Palestra] Keynote: PHP-7PHP Experience 2016 - [Palestra] Keynote: PHP-7
PHP Experience 2016 - [Palestra] Keynote: PHP-7iMasters
 
Introdução ao Ruby
Introdução ao RubyIntrodução ao Ruby
Introdução ao RubyMilton Moura
 
Boas praticas em um Projeto de Banco de Dados
Boas praticas em um Projeto de Banco de DadosBoas praticas em um Projeto de Banco de Dados
Boas praticas em um Projeto de Banco de DadosJuliano Atanazio
 
Palestra DataFlow - II São Paulo Perl Workshop
Palestra DataFlow - II São Paulo Perl WorkshopPalestra DataFlow - II São Paulo Perl Workshop
Palestra DataFlow - II São Paulo Perl WorkshopAlexei Znamensky
 
Full Text Search - Busca Textual no PostgreSQL
Full Text Search -  Busca Textual no PostgreSQLFull Text Search -  Busca Textual no PostgreSQL
Full Text Search - Busca Textual no PostgreSQLJuliano Atanazio
 
Introdução ao PHP - Criação de sites II
Introdução ao PHP - Criação de sites IIIntrodução ao PHP - Criação de sites II
Introdução ao PHP - Criação de sites IIinfo_cimol
 
Workshop - Desenvolvimento web com Drupal 7
Workshop - Desenvolvimento web com Drupal 7Workshop - Desenvolvimento web com Drupal 7
Workshop - Desenvolvimento web com Drupal 7Sérgio Lima
 
Curso completo php
Curso completo phpCurso completo php
Curso completo phpbreninho94
 

Mais procurados (20)

Migrando para o PHP 5
Migrando para o PHP 5Migrando para o PHP 5
Migrando para o PHP 5
 
PHP e MySQL para iniciantes
PHP e MySQL para iniciantesPHP e MySQL para iniciantes
PHP e MySQL para iniciantes
 
Doctrine 2 camada de persistência para php
Doctrine 2   camada de persistência para phpDoctrine 2   camada de persistência para php
Doctrine 2 camada de persistência para php
 
Abstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineAbstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP Doctrine
 
PHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta PerformancePHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta Performance
 
Aula 5 PHP - Criação de sites II
Aula 5 PHP - Criação de sites IIAula 5 PHP - Criação de sites II
Aula 5 PHP - Criação de sites II
 
Programacao funcional
Programacao funcionalProgramacao funcional
Programacao funcional
 
Postgresql +python
Postgresql +pythonPostgresql +python
Postgresql +python
 
Apresentação palestra ireport
Apresentação palestra ireportApresentação palestra ireport
Apresentação palestra ireport
 
PHP Experience 2016 - [Palestra] Keynote: PHP-7
PHP Experience 2016 - [Palestra] Keynote: PHP-7PHP Experience 2016 - [Palestra] Keynote: PHP-7
PHP Experience 2016 - [Palestra] Keynote: PHP-7
 
PHP - Arrays
PHP - ArraysPHP - Arrays
PHP - Arrays
 
Introdução ao Ruby
Introdução ao RubyIntrodução ao Ruby
Introdução ao Ruby
 
Boas praticas em um Projeto de Banco de Dados
Boas praticas em um Projeto de Banco de DadosBoas praticas em um Projeto de Banco de Dados
Boas praticas em um Projeto de Banco de Dados
 
Palestra DataFlow - II São Paulo Perl Workshop
Palestra DataFlow - II São Paulo Perl WorkshopPalestra DataFlow - II São Paulo Perl Workshop
Palestra DataFlow - II São Paulo Perl Workshop
 
Doctrine2 Seminário PHP
Doctrine2 Seminário PHPDoctrine2 Seminário PHP
Doctrine2 Seminário PHP
 
Full Text Search - Busca Textual no PostgreSQL
Full Text Search -  Busca Textual no PostgreSQLFull Text Search -  Busca Textual no PostgreSQL
Full Text Search - Busca Textual no PostgreSQL
 
Introdução ao PHP - Criação de sites II
Introdução ao PHP - Criação de sites IIIntrodução ao PHP - Criação de sites II
Introdução ao PHP - Criação de sites II
 
Workshop - Desenvolvimento web com Drupal 7
Workshop - Desenvolvimento web com Drupal 7Workshop - Desenvolvimento web com Drupal 7
Workshop - Desenvolvimento web com Drupal 7
 
Curso completo php
Curso completo phpCurso completo php
Curso completo php
 
Owasp web app_flaws
Owasp web app_flawsOwasp web app_flaws
Owasp web app_flaws
 

Semelhante a Mapeamento Objeto Relacional com PHP - PHP Conference Brasil 2010

Padrões de Projeto e Boas Práticas em PHP - PHP Conference Brasil 2010
Padrões de Projeto e Boas Práticas em PHP - PHP Conference Brasil 2010Padrões de Projeto e Boas Práticas em PHP - PHP Conference Brasil 2010
Padrões de Projeto e Boas Práticas em PHP - PHP Conference Brasil 2010Flávio Lisboa
 
Palestra Zend Framework PHPSC Conf 2010
Palestra Zend Framework PHPSC Conf 2010Palestra Zend Framework PHPSC Conf 2010
Palestra Zend Framework PHPSC Conf 2010Flávio Lisboa
 
PHP para aplicações Web de grande porte
PHP para aplicações Web  de grande portePHP para aplicações Web  de grande porte
PHP para aplicações Web de grande porteFelipe Ribeiro
 
Prepare-se para o próximo estágio da evolução PHP
Prepare-se para o próximo estágio da evolução PHPPrepare-se para o próximo estágio da evolução PHP
Prepare-se para o próximo estágio da evolução PHPRaphael Almeida
 
O futuro do elephante: as promessas do php para 2019
O futuro do elephante: as promessas do php para 2019O futuro do elephante: as promessas do php para 2019
O futuro do elephante: as promessas do php para 2019Cassio Santos
 
Desenvolvimento Web com Php e jQuery
Desenvolvimento Web com Php e jQueryDesenvolvimento Web com Php e jQuery
Desenvolvimento Web com Php e jQueryFabricio Nogueira
 
Muito prazer, eu sou PHP
Muito prazer, eu sou PHPMuito prazer, eu sou PHP
Muito prazer, eu sou PHPLuís Cobucci
 
Como contribuir-com-open-source-php conference-2016
Como contribuir-com-open-source-php conference-2016Como contribuir-com-open-source-php conference-2016
Como contribuir-com-open-source-php conference-2016Marcos Paulo
 
PHP 5 de Forma Correta e Segura
PHP 5 de Forma Correta e SeguraPHP 5 de Forma Correta e Segura
PHP 5 de Forma Correta e SeguraKleber Silva
 
Aula 01 introdução ao php
Aula 01   introdução ao phpAula 01   introdução ao php
Aula 01 introdução ao phpAdriano Castro
 
Desmistificando web2py - #TDC2011
Desmistificando web2py - #TDC2011Desmistificando web2py - #TDC2011
Desmistificando web2py - #TDC2011Bruno Rocha
 
PW01 - Introdução a programação em PHPv7
PW01 - Introdução a programação em PHPv7PW01 - Introdução a programação em PHPv7
PW01 - Introdução a programação em PHPv7Silvano Oliveira
 

Semelhante a Mapeamento Objeto Relacional com PHP - PHP Conference Brasil 2010 (20)

Padrões de Projeto e Boas Práticas em PHP - PHP Conference Brasil 2010
Padrões de Projeto e Boas Práticas em PHP - PHP Conference Brasil 2010Padrões de Projeto e Boas Práticas em PHP - PHP Conference Brasil 2010
Padrões de Projeto e Boas Práticas em PHP - PHP Conference Brasil 2010
 
Palestra Zend Framework PHPSC Conf 2010
Palestra Zend Framework PHPSC Conf 2010Palestra Zend Framework PHPSC Conf 2010
Palestra Zend Framework PHPSC Conf 2010
 
PHP para aplicações Web de grande porte
PHP para aplicações Web  de grande portePHP para aplicações Web  de grande porte
PHP para aplicações Web de grande porte
 
PHP e banco de dados
PHP e banco de dadosPHP e banco de dados
PHP e banco de dados
 
Prepare-se para o próximo estágio da evolução PHP
Prepare-se para o próximo estágio da evolução PHPPrepare-se para o próximo estágio da evolução PHP
Prepare-se para o próximo estágio da evolução PHP
 
O futuro do elephante: as promessas do php para 2019
O futuro do elephante: as promessas do php para 2019O futuro do elephante: as promessas do php para 2019
O futuro do elephante: as promessas do php para 2019
 
Desenvolvimento Web com Php e jQuery
Desenvolvimento Web com Php e jQueryDesenvolvimento Web com Php e jQuery
Desenvolvimento Web com Php e jQuery
 
Muito prazer, eu sou PHP
Muito prazer, eu sou PHPMuito prazer, eu sou PHP
Muito prazer, eu sou PHP
 
Muito prazer, eu sou PHP
Muito prazer, eu sou PHPMuito prazer, eu sou PHP
Muito prazer, eu sou PHP
 
PHP 5.3 - Introdução
PHP 5.3 - IntroduçãoPHP 5.3 - Introdução
PHP 5.3 - Introdução
 
Módulo de php
Módulo de phpMódulo de php
Módulo de php
 
PHP Tools for Fast coding
PHP Tools for Fast codingPHP Tools for Fast coding
PHP Tools for Fast coding
 
Como contribuir-com-open-source-php conference-2016
Como contribuir-com-open-source-php conference-2016Como contribuir-com-open-source-php conference-2016
Como contribuir-com-open-source-php conference-2016
 
PHP: Evolução
PHP: EvoluçãoPHP: Evolução
PHP: Evolução
 
PHP 5 de Forma Correta e Segura
PHP 5 de Forma Correta e SeguraPHP 5 de Forma Correta e Segura
PHP 5 de Forma Correta e Segura
 
Aula 01 introdução ao php
Aula 01   introdução ao phpAula 01   introdução ao php
Aula 01 introdução ao php
 
PHP, Mercado e Certificações
PHP, Mercado e CertificaçõesPHP, Mercado e Certificações
PHP, Mercado e Certificações
 
PHP 7 - A Maioridade do PHP
PHP 7 - A Maioridade do PHPPHP 7 - A Maioridade do PHP
PHP 7 - A Maioridade do PHP
 
Desmistificando web2py - #TDC2011
Desmistificando web2py - #TDC2011Desmistificando web2py - #TDC2011
Desmistificando web2py - #TDC2011
 
PW01 - Introdução a programação em PHPv7
PW01 - Introdução a programação em PHPv7PW01 - Introdução a programação em PHPv7
PW01 - Introdução a programação em PHPv7
 

Mais de Flávio Lisboa

Criando testes integrados de APIs com PHP
Criando testes integrados de APIs com PHPCriando testes integrados de APIs com PHP
Criando testes integrados de APIs com PHPFlávio Lisboa
 
Cooperativas de Software Livre: Uma comparação entre Brasil e Argentina
Cooperativas de Software Livre: Uma comparação entre Brasil e ArgentinaCooperativas de Software Livre: Uma comparação entre Brasil e Argentina
Cooperativas de Software Livre: Uma comparação entre Brasil e ArgentinaFlávio Lisboa
 
Aprenda a afiar suas garras com Laminas
Aprenda a afiar suas garras com LaminasAprenda a afiar suas garras com Laminas
Aprenda a afiar suas garras com LaminasFlávio Lisboa
 
Ciência e software livre: desenvolvendo com método
Ciência e software livre: desenvolvendo com métodoCiência e software livre: desenvolvendo com método
Ciência e software livre: desenvolvendo com métodoFlávio Lisboa
 
Turbinando microsserviços em PHP
Turbinando microsserviços em PHPTurbinando microsserviços em PHP
Turbinando microsserviços em PHPFlávio Lisboa
 
O que esperar do framework Laminas
O que esperar do framework LaminasO que esperar do framework Laminas
O que esperar do framework LaminasFlávio Lisboa
 
PHP Conference Brazil - What can we expect about framework Laminas?
PHP Conference Brazil - What can we expect about framework Laminas?PHP Conference Brazil - What can we expect about framework Laminas?
PHP Conference Brazil - What can we expect about framework Laminas?Flávio Lisboa
 
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019Flávio Lisboa
 
Criando microsserviços em PHP
Criando microsserviços em PHPCriando microsserviços em PHP
Criando microsserviços em PHPFlávio Lisboa
 
Como se tornar o pior programador PHP do mundo
Como se tornar o pior programador PHP do mundoComo se tornar o pior programador PHP do mundo
Como se tornar o pior programador PHP do mundoFlávio Lisboa
 
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHPA demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHPFlávio Lisboa
 
Comunicação e padrões em código aberto: quando convergente e divergente cooperam
Comunicação e padrões em código aberto: quando convergente e divergente cooperamComunicação e padrões em código aberto: quando convergente e divergente cooperam
Comunicação e padrões em código aberto: quando convergente e divergente cooperamFlávio Lisboa
 
Criação de robôs em PHP para raspagem de dados
Criação de robôs em PHP para raspagem de dadosCriação de robôs em PHP para raspagem de dados
Criação de robôs em PHP para raspagem de dadosFlávio Lisboa
 
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de DadosEstudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de DadosFlávio Lisboa
 
Arquitetura PHP para um mundo orientado a microsserviços
Arquitetura PHP para um mundo orientado a microsserviçosArquitetura PHP para um mundo orientado a microsserviços
Arquitetura PHP para um mundo orientado a microsserviçosFlávio Lisboa
 
Semeando Liberdade: Como (e onde) o software livre inclui as pessoas
Semeando Liberdade: Como (e onde) o software livre inclui as pessoasSemeando Liberdade: Como (e onde) o software livre inclui as pessoas
Semeando Liberdade: Como (e onde) o software livre inclui as pessoasFlávio Lisboa
 
O que é programação de computadores
O que é programação de computadoresO que é programação de computadores
O que é programação de computadoresFlávio Lisboa
 
Economia em rede (comunidade)
Economia em rede (comunidade)Economia em rede (comunidade)
Economia em rede (comunidade)Flávio Lisboa
 
Aplicações Corporativas em PHP (CRM e ERP)
Aplicações Corporativas em PHP (CRM e ERP)Aplicações Corporativas em PHP (CRM e ERP)
Aplicações Corporativas em PHP (CRM e ERP)Flávio Lisboa
 

Mais de Flávio Lisboa (20)

Criando testes integrados de APIs com PHP
Criando testes integrados de APIs com PHPCriando testes integrados de APIs com PHP
Criando testes integrados de APIs com PHP
 
Cooperativas de Software Livre: Uma comparação entre Brasil e Argentina
Cooperativas de Software Livre: Uma comparação entre Brasil e ArgentinaCooperativas de Software Livre: Uma comparação entre Brasil e Argentina
Cooperativas de Software Livre: Uma comparação entre Brasil e Argentina
 
Aprenda a afiar suas garras com Laminas
Aprenda a afiar suas garras com LaminasAprenda a afiar suas garras com Laminas
Aprenda a afiar suas garras com Laminas
 
Ciência e software livre: desenvolvendo com método
Ciência e software livre: desenvolvendo com métodoCiência e software livre: desenvolvendo com método
Ciência e software livre: desenvolvendo com método
 
Turbinando microsserviços em PHP
Turbinando microsserviços em PHPTurbinando microsserviços em PHP
Turbinando microsserviços em PHP
 
O que esperar do framework Laminas
O que esperar do framework LaminasO que esperar do framework Laminas
O que esperar do framework Laminas
 
PHP Conference Brazil - What can we expect about framework Laminas?
PHP Conference Brazil - What can we expect about framework Laminas?PHP Conference Brazil - What can we expect about framework Laminas?
PHP Conference Brazil - What can we expect about framework Laminas?
 
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
Algoritmos Genéticos em PHP - PHP Conference Brasil 2019
 
Criando microsserviços em PHP
Criando microsserviços em PHPCriando microsserviços em PHP
Criando microsserviços em PHP
 
Como se tornar o pior programador PHP do mundo
Como se tornar o pior programador PHP do mundoComo se tornar o pior programador PHP do mundo
Como se tornar o pior programador PHP do mundo
 
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHPA demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
A demanda da santa entrega Batman: bugs e gargalos em aplicações PHP
 
Comunicação e padrões em código aberto: quando convergente e divergente cooperam
Comunicação e padrões em código aberto: quando convergente e divergente cooperamComunicação e padrões em código aberto: quando convergente e divergente cooperam
Comunicação e padrões em código aberto: quando convergente e divergente cooperam
 
Criação de robôs em PHP para raspagem de dados
Criação de robôs em PHP para raspagem de dadosCriação de robôs em PHP para raspagem de dados
Criação de robôs em PHP para raspagem de dados
 
Amanhecer esmeralda
Amanhecer esmeraldaAmanhecer esmeralda
Amanhecer esmeralda
 
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de DadosEstudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
Estudo de Caso: Utilização de PHP no Serviço Federal de Processamento de Dados
 
Arquitetura PHP para um mundo orientado a microsserviços
Arquitetura PHP para um mundo orientado a microsserviçosArquitetura PHP para um mundo orientado a microsserviços
Arquitetura PHP para um mundo orientado a microsserviços
 
Semeando Liberdade: Como (e onde) o software livre inclui as pessoas
Semeando Liberdade: Como (e onde) o software livre inclui as pessoasSemeando Liberdade: Como (e onde) o software livre inclui as pessoas
Semeando Liberdade: Como (e onde) o software livre inclui as pessoas
 
O que é programação de computadores
O que é programação de computadoresO que é programação de computadores
O que é programação de computadores
 
Economia em rede (comunidade)
Economia em rede (comunidade)Economia em rede (comunidade)
Economia em rede (comunidade)
 
Aplicações Corporativas em PHP (CRM e ERP)
Aplicações Corporativas em PHP (CRM e ERP)Aplicações Corporativas em PHP (CRM e ERP)
Aplicações Corporativas em PHP (CRM e ERP)
 

Mapeamento Objeto Relacional com PHP - PHP Conference Brasil 2010

  • 1. Flávio Lisboa - PHP Conference 2010 Mapeamento Objeto Relacional com PHP Flávio Gomes da Silva Lisboa @fgsl www.fgsl.eti.br @fgsl A reprodução é livre, apenas cite a fonte
  • 2. Flávio Lisboa - PHP Conference 2010 Quem sou eu 2007 2008 2009 A reprodução é livre, apenas cite a fonte @fgsl
  • 3. Flávio Lisboa - PHP Conference 2010 ►Problemas ►Soluções ►Opções: Mapeamento Objeto Relacional A reprodução é livre, apenas cite a fonte @fgsl
  • 4. Flávio Lisboa - PHP Conference 2010 Problemas A maioria das aplicações Web persistem dados em um banco de dados. A reprodução é livre, apenas cite a fonte @fgsl
  • 5. Flávio Lisboa - PHP Conference 2010 Problemas O processo de desenvolvimento utiliza conexões diferentes (desenvolvimento, teste, homologação e produção). Adaptado de sofist.com.br A reprodução é livre, apenas cite a fonte @fgsl
  • 6. Flávio Lisboa - PHP Conference 2010 Problemas Uma aplicação pode utilizar-se de várias fontes de dados diferentes ao mesmo tempo. A reprodução é livre, apenas cite a fonte @fgsl
  • 7. Flávio Lisboa - PHP Conference 2010 Problemas E ela também pode ser distribuída para trabalhar com bases de dados que tem a mesma estrutura, mas são fornecidas por fabricantes diferentes, por exemplo, MySQL e PostgreSQL. A reprodução é livre, apenas cite a fonte @fgsl
  • 8. Flávio Lisboa - PHP Conference 2010 Problemas Por isso, código específico para manipular um determinado mecanismo de persistência e recuperação de dados não deve ficar espalhado pela aplicação. A reprodução é livre, apenas cite a fonte @fgsl
  • 9. Flávio Lisboa - PHP Conference 2010 Problemas Além disso, o banco de dados deve ficar desacoplado da aplicação, para que mudanças no banco (como alterações em nomes de campos de tabelas) não gerem trabalho de recodificação. infoescola.com A reprodução é livre, apenas cite a fonte @fgsl
  • 10. Flávio Lisboa - PHP Conference 2010 Soluções Mapear dados de objetos para bancos de dados relacionais Referência: Padrões de Arquitetura de Aplicações Corporativas Martin Fowler, arquiteto de software e consultor A reprodução é livre, apenas cite a fonte @fgsl
  • 11. Flávio Lisboa - PHP Conference 2010 Momento Cultural O que é um arquiteto de software? A reprodução é livre, apenas cite a fonte
  • 12. Flávio Lisboa - PHP Conference 2010 Momento Cultural E o que é um consultor? * to con: enganar * demeaning: degradante Dilbert, by Scott Adams A reprodução é livre, apenas cite a fonte
  • 13. Flávio Lisboa - PHP Conference 2010 Momento Cultural E o que é um consultor? A reprodução é livre, apenas cite a fonte
  • 14. Flávio Lisboa - PHP Conference 2010 Momento Cultural E o que é um consultor? Dilbert, by Scott Adams A reprodução é livre, apenas cite a fonte
  • 15. Flávio Lisboa - PHP Conference 2010 Soluções Embora existam várias técnicas para embutir SQL em uma linguagem de programação, elas são todas um pouco deselegantes. A reprodução é livre, apenas cite a fonte @fgsl
  • 16. Flávio Lisboa - PHP Conference 2010 Soluções Seria melhor acessar os dados usando mecanismos que se encaixem com a linguagem de desenvolvimento da aplicação. A reprodução é livre, apenas cite a fonte @fgsl
  • 17. Flávio Lisboa - PHP Conference 2010 Soluções Por essas razões, é sábio separar o acesso SQL da lógica de domínio e colocá-las em classes separadas. A reprodução é livre, apenas cite a fonte @fgsl
  • 18. Flávio Lisboa - PHP Conference 2010 Soluções Padrões de Projeto: soluções reutilizáveis de software orientado a objetos The Greatest American Hero, by Stephen J. Cannell, starring William Kat A reprodução é livre, apenas cite a fonte @fgsl
  • 19. Flávio Lisboa - PHP Conference 2010 Soluções Padrões de Projeto: soluções reutilizáveis de software orientado a objetos Abin Sur, Hal Jordan, Green Lanterns created by John Broome and Gil Kane A reprodução é livre, apenas cite a fonte @fgsl
  • 20. Flávio Lisboa - PHP Conference 2010 Soluções Padrão Básico Gateway Um objeto que encapsula o acesso a um sistema ou recurso externo A reprodução é livre, apenas cite a fonte @fgsl
  • 21. Flávio Lisboa - PHP Conference 2010 Soluções Gateway API simples para lidar de forma orientada a objetos com coisas que não são objetos A reprodução é livre, apenas cite a fonte @fgsl
  • 22. Flávio Lisboa - PHP Conference 2010 Soluções Padrões de Mapeamento Objeto Relacional Row Data Gateway Um objeto para cada linha retornada por uma consulta Utilidade: trabalhar com um registro específico Table Data Gateway Um objeto para cada tabela Utilidade: trabalhar com um conjunto de registros A reprodução é livre, apenas cite a fonte @fgsl
  • 23. Flávio Lisboa - PHP Conference 2010 Soluções Padrões de Mapeamento Objeto Relacional Active Record Um objeto de domínio cliente sabe como interagir com tabelas do banco de dados Data Mapper Isola os objetos do domínio do banco de dados A reprodução é livre, apenas cite a fonte @fgsl
  • 24. Flávio Lisboa - PHP Conference 2010 Soluções Diferenças Active Record O objeto de domínio sabe como incluir, alterar, excluir e pesquisar. Data Mapper O objeto de domínio invoca um objeto que sabe como incluir, alterar, excluir e pesquisar. A reprodução é livre, apenas cite a fonte @fgsl
  • 25. Flávio Lisboa - PHP Conference 2010 Soluções Preciso implementar tudo isso? A reprodução é livre, apenas cite a fonte @fgsl
  • 26. Flávio Lisboa - PHP Conference 2010 Soluções A reprodução é livre, apenas cite a fonte @fgsl
  • 27. Flávio Lisboa - PHP Conference 2010 Soluções A reprodução é livre, apenas cite a fonte @fgsl Use um framework ORM framework... ...abstração que une códigos comuns entre vários projetos de software provendo uma funcionalidade genérica... Fonte: http://pt.wikipedia.org/wiki/Framework Aplicações Camada de ModeloCamada de Modelo Objeto de domínio Framework ORM
  • 28. Flávio Lisboa - PHP Conference 2010 Opções A reprodução é livre, apenas cite a fonte @fgsl
  • 29. Flávio Lisboa - PHP Conference 2010 Opções A reprodução é livre, apenas cite a fonte @fgsl Estudo de caso: cadastro de livros e categorias de livros
  • 30. Flávio Lisboa - PHP Conference 2010 Opções A reprodução é livre, apenas cite a fonte @fgsl Estudo de caso: cadastro de livros e categorias de livros CREATE TABLE `livrosdb`.`livros` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT , `titulo` VARCHAR( 80 ) NOT NULL , `id_categoria` INT UNSIGNED NOT NULL , PRIMARY KEY ( `id` ) , INDEX ( `titulo` , `id_categoria` ) ) ENGINE = InnoDB CREATE DATABASE `livrosdb` ; CREATE TABLE `livrosdb`.`categorias` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT , `nome` VARCHAR( 80 ) NOT NULL , PRIMARY KEY ( `id` ) , INDEX ( `nome` ) ) ENGINE = InnoDB
  • 31. Flávio Lisboa - PHP Conference 2010 Opções A reprodução é livre, apenas cite a fonte @fgsl Projeto PHP com três implementações: propel doctrine zenddb exemploormphp
  • 32. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl http://www.propelorm.org Pode ser instalado pelo Depende de PHing Is Not GNU make baseado em que também pode instalar ►Versão 1.5.2 requer PHP 5.2.4 ►Usa PDO ►É usado pelo http://www.phing.info
  • 33. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Possui dois componentes: Um gerador de modelos: não obrigatório. (mas se não usar vai ficar muito difícil...) propel-1.5.2/generator/bin/propel-gen (Linux) propel-1.5.2/generator/bin/propel-gen.bat (Windows) Uma biblioteca de classes: necessária
  • 34. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Neste caso, foram instalados manualmente o propel 1.5.2 e o phing 2.4.2 no Linux. Foram criados links simbólicos para os scripts do Propel e do Phing no diretório /usr/bin. O script do Phing precisa de permissão de execução para ser chamado pelo Propel.
  • 35. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Diretiva Valor ze1_compatibility_mode Off magic_quotes_gpc Off magic_quotes_sybase Off Configuração do php.ini
  • 36. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl schema.xml (raiz do projeto) <?xml version="1.0" encoding="UTF-8"?> <database name="livrosdb" defaultIdMethod="native"> <table name="livros" phpName="Livro"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="titulo" type="varchar" size="80" required="true" /> <column name="id_categoria" type="integer" required="true" /> <foreign-key foreignTable="categorias"> <reference local="id_categoria" foreign="id" /> </foreign-key> </table> <table name="categorias" phpName="Categoria"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="nome" type="varchar" size="80" required="true" /> </table> </database>
  • 37. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl build.properties (raiz do projeto) # Database driver propel.database = mysql # Project name propel.project = propel
  • 38. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Entre no diretório do projeto e execute o comando: propel-gen om
  • 39. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl [propel-om] Processing: schema.xml [propel-om] Processing Datamodel : schema.xml [propel-om] - processing database : livrosdb [propel-om] + livros [propel-om] -> BaseLivroPeer [builder: PHP5PeerBuilder] [propel-om] -> BaseLivro [builder: PHP5ObjectBuilder] [propel-om] -> LivroTableMap [builder: PHP5TableMapBuilder] [propel-om] -> BaseLivroQuery [builder: QueryBuilder] [propel-om] -> LivroPeer [builder: PHP5ExtensionPeerBuilder] [propel-om] -> Livro [builder: PHP5ExtensionObjectBuilder] [propel-om] -> LivroQuery [builder: ExtensionQueryBuilder] [propel-om] + categorias [propel-om] -> BaseCategoriaPeer [builder: PHP5PeerBuilder] [propel-om] -> BaseCategoria [builder: PHP5ObjectBuilder] [propel-om] -> CategoriaTableMap [builder: PHP5TableMapBuilder] [propel-om] -> BaseCategoriaQuery [builder: QueryBuilder] [propel-om] -> CategoriaPeer [builder: PHP5ExtensionPeerBuilder] [propel-om] -> Categoria [builder: PHP5ExtensionObjectBuilder] [propel-om] -> CategoriaQuery [builder: ExtensionQueryBuilder] [propel-om] Object model generation complete - 14 files written
  • 40. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Pra cada tabela, Propel cria 3 arquivos (que você vai utilizar diretamente): Uma classe modelo que representa uma linha no banco de dados; Uma classe peer com constantes estáticas e métodos para compatibilidade com versões anteriores de Propel; Uma classe query, para operar sobre a tabela para recuperar e atualizar registros
  • 41. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Propel pode gerar o script SQL das tabelas com o comando: propel-gen sql O script é gravado no arquivo build/sql/schema.sql
  • 42. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Propel também pode criar as tabelas no banco, configurando a conexão no build.properties. propel.database.url = [DSN padrão PDO] propel.database.user = propel.database.password = propel-gen sql
  • 43. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl É preciso criar o arquivo runtime-conf.xml na raiz do projeto, com as conexões a serem usadas em tempo de execução <?xml version="1.0" encoding="UTF-8"?> <config> <propel> <datasources default="livrosdb"> <datasource id="livrosdb"> <adapter>mysql</adapter> <!-- sqlite, mysql, myssql, oracle, or pgsql --> <connection> <dsn>mysql:host=localhost;dbname=livrosdb</dsn> <user>root</user> <password>admin</password> </connection> </datasource> </datasources> </propel> </config>
  • 44. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Por questão de performance (tempo de parsing do XML), Propel usa uma versão PHP do arquivo runtime-conf.xml. Essa versão é gerada com o comando: propel-gen convert-conf
  • 45. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Para usar o Propel na aplicação, você precisa: 1)Adicionar o diretório runtime/lib do Propel no include_path do PHP 2)Importar o arquivo Propel.php 3)Carregar a configuração das conexões 4)Adicionar o diretório build/classes da aplicação no include_path do PHP
  • 46. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Algo assim: <?php define(BASE_PATH, substr(realpath(__FILE__),0,strpos(realpath(__FILE__),'exemploormphp'))); define(APPLICATION, 'exemploormphp/propel'); set_include_path(get_include_path() . PATH_SEPARATOR . BASE_PATH.'propel- 1.5.2/runtime/lib'); // Inclui o script principal do Propel require_once 'Propel.php'; // Inicia a configuração de tempo de execução Propel::init(BASE_PATH.APPLICATION.'/build/conf/propel-conf.php'); // Adiciona o diretório 'classes' ao include path set_include_path(BASE_PATH.APPLICATION.'/build/classes' . PATH_SEPARATOR . get_include_path()); exemploormphp/propel/init.php
  • 47. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Exemplo de inclusão exemploormphp/propel/create.php require_once 'init.php'; $nome = (string) $_GET['nome']; $categoria = new Categoria(); $categoria->setNome($nome); $categoria->save(); unset($categoria);
  • 48. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Exemplo de consulta exemploormphp/propel/recover.php require_once 'init.php'; $id = (int) $_GET['id']; $nome = (string) $_GET['nome']; if (!empty($id)) $categoria = CategoriaQuery::create()->findPk($id); if (!empty($nome)) $categoria = CategoriaQuery::create()->findOneByNome($nome); echo 'Nome: ' . $categoria->getNome();
  • 49. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Exemplo de alteração exemploormphp/propel/update.php require_once 'init.php'; $id = (int) $_GET['id']; $nome = (string) $_GET['nome']; if (!empty($id)) $categoria = CategoriaQuery::create()->findPk($id); if (!empty($nome)) $categoria = CategoriaQuery::create()->findOneByNome($nome); $categoria->setNome('Huguinho'); $categoria->save(); $id = $categoria->getId(); unset($categoria); $categoria = CategoriaQuery::create()->findPk($id); echo 'Nome: ' . $categoria->getNome();
  • 50. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Exemplo de exclusão exemploormphp/propel/delete.php require_once 'init.php'; $id = (int) $_GET['id']; $nome = (string) $_GET['nome']; if (!empty($id)) $categoria = CategoriaQuery::create()->findPk($id); if (!empty($nome)) $categoria = CategoriaQuery::create()->findOneByNome($nome); print_r($categoria); $categoria->delete(); print_r($categoria); O objeto ainda existe, mas não é mais persistente. O estado pode ser verificado com o método isDeleted().
  • 51. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Exemplo de consulta a vários registros exemploormphp/propel/listing.php require_once 'init.php'; $categoria = CategoriaQuery::create()- >findOneByNome('suspense'); $livros = LivroQuery::create()- >filterByCategoria($categoria)->orderByTitulo()->find(); foreach($livros as $livro) { print_r($livro); }
  • 52. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Exemplo de consulta SQL customizada exemploormphp/propel/sqlisting.php require_once 'init.php'; $con = Propel::getConnection(LivroPeer::DATABASE_NAME); $sql = 'SELECT l.id, l.titulo,c.nome '; $sql .= 'FROM livros as l INNER JOIN categorias as c '; $sql .= 'ON l.id_categoria = c.id '; $sql .= 'WHERE c.nome = :name'; $stmt = $con->prepare($sql); $stmt->execute(array(':name' => 'suspense')); $formatter = new PropelObjectFormatter(); $formatter->setClass('Livro'); $formatter->setPeer('LivroPeer'); $livros = $formatter->format($stmt); foreach($livros as $livro) { print_r($livro); }
  • 53. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Exemplo de efeito de relacionamento exemploormphp/propel/relation.php require_once 'init.php'; $categoria = new Categoria(); $categoria->setNome('suspense'); $livro = new Livro(); $livro->setTitulo('A volta dos que não foram'); $livro->setCategoria($categoria); $livro->save(); unset($livro); $livro = LivroQuery::create()->filterByCategoria($categoria)- >findOne(); echo 'Título: ' . $livro->getTitulo().'<br/>'; echo 'Categoria: ' . $livro->getCategoria()->getNome();
  • 54. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Transações $con = Propel::getConnection(CategoriaPeer::DATABASE_NAME); $con->beginTransaction(); Try { O QUE VOCÊ ESPERA QUE OCORRA $con->commit(); } catch (Exception $e) { O QUE OCORRE $con->rollback(); throw $e; }
  • 55. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl Ganchos Class Livro extends BaseLivro public function postSave(PropelPDO $con) { ... } public function postDelete(PropelPDO $con) { ... } public function updateCategoria(PropelPDO $con) { ... } }
  • 56. Flávio Lisboa - PHP Conference 2010 Propel A reprodução é livre, apenas cite a fonte @fgsl
  • 57. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl http://www.doctrine-project.org Mapeador Objeto Relacional Camada de Abstração de Banco de Dados ORM DBAL usa ►Versão 1.2.3 requer PHP 5.2.3 ►Usa PDO ►Versão 2.0 usa PHP 5.3 e é... TOTALMENTE DIFERENTE! Pode ser instalado pelo MongoDB ODM Migrations Common
  • 58. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Neste caso, foi instalado manualmente o Doctrine 1.2.3 no Linux. Foi criado um diretório lib/vendor/doctrine no projeto, com links simbólicos para o diretório Doctrine e para o arquivo Doctrine.php.
  • 59. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Inicialização do Doctrine: exemploormphp/doctrine/init.php set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/lib/vendor/doctrine'); require_once('Doctrine.php'); spl_autoload_register(array('Doctrine', 'autoload')); spl_autoload_register(array('Doctrine', 'modelsAutoload')); $manager = Doctrine_Manager::getInstance(); $dsn = 'mysql:dbname=livrosdb;host=127.0.0.1'; $user = 'root'; $password = 'admin'; $dbh = new PDO($dsn,$user,$password); $conn = $manager->connection($dbh,'livrosdb'); Doctrine_Core::loadModels(array('models','models/generated'));
  • 60. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Doctrine possuía uma ferramenta de linha de comando, com geração de código, similar ao Propel. Essa ferramenta estava disponível na distribuição Sandbox. Só que a Sandbox não está mais disponível... Na versão 2.0, a linha de comando já vem incluída no ORM padrão. Mas aqui não estamos falando da versão 2.0...
  • 61. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Mas isso não significa que não dê pra gerar os modelos! Duffy Duck by Warner Bros
  • 62. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Crie no projeto uma pasta chamada models. Crie na raiz do projeto um script que invoque o método generateModelsFromDb da classe Doctrine_Core: require_once 'init.php'; Doctrine_Core::generateModelsFromDb('models', array('livrosdb'), array('generateTableClasses' => true)); exempoormphp/doctrine/gom.php
  • 63. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl São geradas três classes para cada tabela... As classes com prefixo Base contém a definição da tabela e são herdadas pela classe que implementa ActiveRecord. A classe com sufixo Table é um Data Mapper.
  • 64. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Para não gerar os Data Mappers, a chave generateTableClasses do método generateModelsFromDb deve ser configurada para false. Você pode apagar os arquivos também, se quiser. Dee Dee & Dexter by Hanna Barbera
  • 65. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Mas é preciso verificar os relacionamentos gerados. No nosso exemplo, o Doctrine gera um relacionamentos um-pra-muitos entre Livros e Categorias, sendo que na verdade é um-pra-um. class Livros extends BaseLivros { public function setUp() { parent::setUp(); $this->hasOne('Categorias', array( 'local' => 'id_categoria', 'foreign' => 'id' ) ); } }
  • 66. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Também é possível criar scripts com as definições das tabelas com o Doctrine DBAL. Esses scripts podem ter a conexão parametrizada, de forma a gerar tabelas para qualquer banco de dados. Também é possivel criar definições de tabelas no formato YAML (Yaml Ain't Markup Language), criar os modelos a partir delas e aí gerar as tabelas. DBAL
  • 67. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Exemplo de inclusão exemploormphp/doctrine/create.php require_once 'init.php'; $nome = (string) $_GET['nome']; $categoria = new Categorias(); $categoria->nome = $nome; $categoria->save(); unset($categoria);
  • 68. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Exemplo de consulta exemploormphp/doctrine/recover.php require_once 'init.php'; $id = (int) $_GET['id']; $nome = (string) $_GET['nome']; $categoriaTable = CategoriasTable::getInstance(); if (!empty($id)) $categoria = $categoriaTable->findOneById($id); if (!empty($nome)) $categoria = $categoriaTable->findOneByNome($nome); echo 'Nome: ' . $categoria->nome;
  • 69. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Exemplo de alteração exemploormphp/doctrine/update.php require_once 'init.php'; $id = (int) $_GET['id']; $nome = (string) $_GET['nome']; if (!empty($id)) $categoria = CategoriasTable::getInstance()->find($id); if (!empty($nome)) $categoria = CategoriasTable::getInstance()->findOneByNome($nome); $categoria->nome = 'Huguinho'; $categoria->save(); $id = $categoria->id; unset($categoria); $categoria = CategoriasTable::getInstance()->find($id); echo 'Nome: ' . $categoria->nome;
  • 70. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Exemplo de exclusão exemploormphp/doctrine/delete.php require_once 'init.php'; $id = (int) $_GET['id']; $nome = (string) $_GET['nome']; if (!empty($id)) $categoria = CategoriasTable::getInstance()->find($id); if (!empty($nome)) $categoria = CategoriasTable::getInstance()- >findOneByNome($nome); print_r($categoria); $categoria->delete(); print_r($categoria); O objeto ainda existe, mas não é mais persistente. O estado pode ser verificado com o método state().
  • 71. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Exemplo de consulta a vários registros exemploormphp/doctrine/listing.php require_once 'init.php'; $livros = LivrosTable::getInstance()- >findByDql('Categorias.nome = ?','romance'); echo 'Quantidade de livros: ' . count($livros); foreach($livros as $livro) { print_r($livro); }
  • 72. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Exemplo de consulta SQL customizada exemploormphp/doctrine/sqlisting.php require_once 'init.php'; $q = Doctrine_Query::create($conn) ->select('l.id, l.titulo, c.nome') ->from('Livros l') ->innerJoin('l.Categorias c') ->where('c.nome = ?'); $livros = $q->execute(array('romance')); echo 'Quantidade de livros: ' . count($livros); foreach($livros as $livro) { print_r($livro); }
  • 73. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Exemplo de efeito de relacionamento exemploormphp/doctrine/relation.php require_once 'init.php'; $categoria = new Categorias(); $categoria->nome = 'romance'; $livro = new Livros(); $livro->titulo = 'Poeira em alto mar'; $livro->Categorias = $categoria; $livro->save(); unset($livro); $livro = LivrosTable::getInstance()- >findByDql('Categorias.nome = ?','romance')->get(0); echo 'Título: ' . $livro->titulo . '<br/>'; echo 'Categoria: ' . $livro->Categorias->nome;
  • 74. Flávio Lisboa - PHP Conference 2010 $conn = beginTransaction(); Try { O QUE VOCÊ ESPERA QUE OCORRA $conn->commit(); } catch (Exception $e) { O QUE OCORRE $conn->rollback(); throw $e; } Doctrine A reprodução é livre, apenas cite a fonte @fgsl Transações
  • 75. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl Ganchos Class Livros extends BaseLivros public function preSave($event) { ... } public function postSave($event) { ... } public function postDqlSelect($event) { ... } }
  • 76. Flávio Lisboa - PHP Conference 2010 Doctrine A reprodução é livre, apenas cite a fonte @fgsl
  • 77. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl ►Versão 1.10 requer PHP 5.2.4 ►Usa PDO ►Versão 2.0 usará PHP 5.3 e terá ... MUITA COISA LEGAL! Pode ser instalado pelo ...mas por um canal não oficial Zend_Db_Adapter Zend_Db_Profiler Zend_Db_Select Zend_Db_Statement Zend_Db_Table
  • 78. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Neste caso, foi instalado manualmente o Zend Framework 1.10.6. Na raiz do projeto foi criado um link simbólico para o diretório ZendFramework-1.10.6/library/Zend. Na raiz do projeto foi criada uma pasta models para armazenar os modelos.
  • 79. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl require_once 'Zend/Loader/Autoloader.php'; set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/models'); $autoloader = Zend_Loader_Autoloader::getInstance(); $autoloader->registerNamespace('Zend_Config_*'); $autoloader->registerNamespace('Zend_Db_*'); $config = new Zend_Config_Ini('config.ini','database'); $conn = Zend_Db::factory($config->db->adapter,$config->db- >params->toArray()); exemploormphp/zenddb/init.php Inicialização do Zend_Db:
  • 80. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl exemploormphp/zenddb/config.ini Configuração da conexão: [database] db.adapter = PDO_MYSQL db.params.username = root db.params.password = admin db.params.dbname = livrosdb db.params.host = localhost
  • 81. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Zend Framework possui um componente chamado Zend_Tool, que é uma ferramenta de linha de comando para geração de código. Zend_Tool cria as classes de modelo, mas somente quando o projeto foi criado com a estrutura do Zend_Framework, porque as definições são lidas e gravadas no arquivo .zfproject.xml.
  • 82. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Por outro lado, você não precisa necessariamente criar a classe de modelo para manipular o banco porque o Zend_Db provê uma implementação genérica de Data Mapper. Basta instanciar Zend_Db_Table passando para o construtor o nome da tabela no banco de dados.
  • 83. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Exemplo de inclusão com Data Mapper: exemploormphp/zenddb/createwithoutmodel.php require_once 'init.php'; $categoria = new Zend_Db_Table('categorias'); $categoria->insert(array('nome'=>'infantil')); unset($categoria);
  • 84. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Mas a criação do modelo é fácil: exemploormphp/zenddb/models/Categoria.php class Categoria extends Zend_Db_Table_Abstract { protected $_name = 'categorias'; }
  • 85. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Exemplo de inclusão com modelo definido: exemploormphp/zenddb/create.php require_once 'init.php'; Zend_Loader::loadClass('Categoria'); $dm = new Categoria(); $categoria = $dm->createRow(); $categoria->nome = 'infantil'; $categoria->save(); unset($categoria);
  • 86. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Exemplo de consulta exemploormphp/zenddb/recover.php require_once 'init.php'; $id = (int) $_GET['id']; $nome = (string) $_GET['nome']; Zend_Loader::loadClass('Categoria'); $dm = new Categoria(); if (!empty($id)) $categoria = $dm->find($id)->current(); if (!empty($nome)) $categoria = $dm->fetchRow($dm->getDefaultAdapter()->quoteInto('nome = ?', $nome)); echo 'Nome: ' . $categoria->nome;
  • 87. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Exemplo de alteração exemploormphp/zenddb/update.php require_once 'init.php'; $id = (int) $_GET['id']; $nome = (string) $_GET['nome']; Zend_Loader::loadClass('Categoria');$dm = new Categoria(); if (!empty($id)) $categoria = $dm->find($id)->current(); if (!empty($nome)) $categoria = $dm->fetchRow($dm->getDefaultAdapter()->quoteInto('nome = ?',$nome)); $categoria->nome = 'Huguinho'; $categoria->save(); $id = $categoria->id; unset($categoria); $categoria = $dm->find($id)->current(); echo 'Nome: ' . $categoria->nome;
  • 88. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Exemplo de exclusão exemploormphp/zenddb/delete.php require_once 'init.php'; $id = (int) $_GET['id']; $nome = (string) $_GET['nome']; Zend_Loader::loadClass('Categoria'); $dm = new Categoria(); if (!empty($id)) $categoria = $dm->find($id)->current(); if (!empty($nome)) $categoria = $dm->fetchRow($dm->getDefaultAdapter()->quoteInto('nome = ?', $nome)); print_r($categoria->id); $categoria->delete(); print_r($categoria->id); O objeto ainda existe, mas seus atributos estão vazios.
  • 89. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Relacionamento no Modelo exemploormphp/zenddb/models/Livro.php class Livro extends Zend_Db_Table_Abstract { protected $_name = 'livros'; protected $_referenceMap = array( 'Categoria' => array( 'columns' => 'id_categoria', 'refTableClass' => 'Categoria', 'refColumns' => 'id' )); }
  • 90. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Exemplo de consulta a vários registros exemploormphp/zenddb/listing.php require_once 'init.php'; Zend_Loader::loadClass('Categoria'); $dm = new Categoria(); $categoria = $dm->fetchRow($dm->getDefaultAdapter()- >quoteInto('nome = ?','infantil')); $livros = $categoria->findDependentRowset('Livro'); echo 'Quantidade de livros: ' . count($livros); foreach($livros as $livro) { print_r($livro); }
  • 91. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Exemplo de consulta SQL customizada exemploormphp/zenddb/sqlisting.php require_once 'init.php'; Zend_Loader::loadClass('Livro'); $dm = new Livro(); $select = $dm->select(Zend_Db_Table::SELECT_WITH_FROM_PART) ->setIntegrityCheck(false); $select->join('categorias','livros.id_categoria = categorias.id') ->where('categorias.nome = ?','infantil'); $livros = $dm->fetchAll($select); echo 'Quantidade de livros: ' . count($livros); foreach($livros as $livro) { print_r($livro); }
  • 92. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Exemplo de efeito de relacionamento exemploormphp/zenddb/relation.php require_once 'init.php'; Zend_Loader::loadClass('Livro');Zend_Loader::loadClass('Categoria'); Zend_Loader::loadClass('LivroRow'); $dmc = new Categoria(); $categoria = $dmc->createRow(); $categoria->nome = 'tragédia'; $dml = new Livro(array('rowClass' => 'LivroRow')); $livro = $dml->createRow(); $livro->titulo = 'Afoguei meu peixinho dourado'; $livro->setCategoria($categoria); $livro->save(); $livro->refresh(); $id = $livro->id; unset($livro); $livro = $dml->find($id)->current(); echo 'Título: ' . $livro->titulo . '<br/>'; echo 'Categoria: ' . $livro->findParentRow('Categoria')->nome;
  • 93. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Atualização automática de registro relacionado exemploormphp/zenddb/models/LivroRow.php class LivroRow extends Zend_Db_Table_Row_Abstract { private $_categoria; public function setCategoria($categoria) { $this->_categoria = $categoria; } public function save() { $this->_categoria->save(); $this->id_categoria = $this->_categoria->id; parent::save(); } }
  • 94. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Este é um projeto GPLv2, que já faz de forma transparente o que foi feito usando a extensão de Zend_Db_Table_Row_Abstract. Ele vem pronto para trabalhar com MySQL, mas por herança é possível criar adaptadores para outros bancos. Há uma proposta em construção, para criar uma nova implementação de ActiveRecord no Zend Framework: http://code.google.com/p/zend-framework-orm http://framework.zend.com/wiki/display/ZFPROP/Zend_Db_ActiveRecord
  • 95. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Transações $conn = Zend_Db_Table_Abstract::getDefaultAdapter(); $conn->beginTransaction(); Try { O QUE VOCÊ ESPERA QUE OCORRA $conn->commit(); } catch (Exception $e) { O QUE OCORRE $conn->rollback(); throw $e; }
  • 96. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl Ganchos Class LivroRow extends Zend_Db_Table_Row_Abstract protected function _insert() { ... } protected function _postInsert() { ... } protected function _update() { ... } }
  • 97. Flávio Lisboa - PHP Conference 2010 Zend_Db A reprodução é livre, apenas cite a fonte @fgsl
  • 98. Flávio Lisboa - PHP Conference 2010 E agora, o que eu faço? A reprodução é livre, apenas cite a fonte @fgsl
  • 99. Flávio Lisboa - PHP Conference 2010 Sei lá, entende? A reprodução é livre, apenas cite a fonte @fgsl Patropi, interpretado por Orival Pessini
  • 100. Flávio Lisboa - PHP Conference 2010 A reprodução é livre, apenas cite a fonte @fgsl Bill Karwin Mas como com qualquer ORM, há, inevitavelmente, algumas consultas SQL e operações que você não pode fazer através da interface OO. Nenhum ORM pode servir como um shopping que tem apenas uma loja.
  • 101. Flávio Lisboa - PHP Conference 2010 A reprodução é livre, apenas cite a fonte @fgsl Independente de sua escolha, saiba que Zend Framework trabalha com todos! Wheelie and The Chopper Bunch (NBC,1974)
  • 102. Flávio Lisboa - PHP Conference 2010 Coisas Realmente Importantes A reprodução é livre, apenas cite a fonte @fgsl Flexibilidade
  • 103. Flávio Lisboa - PHP Conference 2010 Coisas Realmente Importantes A reprodução é livre, apenas cite a fonte @fgsl Facilidade de Manutenção Kombi, Volkswagen
  • 104. Flávio Lisboa - PHP Conference 2010 Obrigado! A reprodução é livre, apenas cite a fonte @fgsl www.fgsl.eti.br Little Einsteins by Walt Disney