Olá. Neste post pretendo demonstrar um exemplo simples e prático de como usar o PHP orientado a objetos no esquema MVC ( Model View Controller ). ). Observação : esse esquema passa a funcionar muito bem a partir do PHP 5.3 O resultado final será uma página que lista os clientes cadastrados. (nos próximos posts de PHP posso detalhar as funções CRUD) Não pretendo discutir os conceitos de MVC, apenas mostrar sua implementação implementação em PHP, destacando a facilidade de construção e manutenção de código, quando as partes (camadas) da aplicação estão separadas em : M- Modelo de Dados: estrutura dos Objetos (Classes) V-View: Interface de apresentação dos dados p/ o Usuário (Telas ou páginas) C- Controle : Regras de negócios (Componentes e Controllers) Essas camadas devem ser independentes, independentes, ou seja : se mudar alguma regra de negócio, esta deve ser implementada na camada de Controle, assim como se a interface for alterada, não existe a a necessidade de se mexer nas regras. Eu costumo utilizar mais uma "camada" em minhas aplicações conhecida como DAO (Data Access Object) que é a camada responsável pela comunicação com o Banco de Dados. Esta é utilizada pela camada de Controle para carregar os Modelos com os dados e entregar para as Views.
Figura 1- Resumo MVC
Exemplo de organização de código : (Neste exemplo mostrarei com a seção clientes)
Figura 2- Estrutura de pastas e arquivos
--App : --Controller : cada Objeto tem o seu , é onde ficam as regras de negócio
--DAO : cada Objeto tem o seu
--Model : quase todas as entidades do DB possuem o seu Objeto e outras informações que sejam compartilhadas em várias seções do site
View : cada Objeto tem sua pasta com as operações básicas de qualquer CRUD (Create Read Update Delete) e um índice (lista inicial) C-> add.php R-> view.php U-> edit.php D-> remove.php
--lib : pasta que contém as principais funções compartilhadas do sistema.
pastas com itens de layout do site : --css : estilos css --images : imagens da seção pública --img : imagens da seção privada --js : arquivos javascript --pages : as páginas do site --static_includes : arquivos que não mudam : meta-tags, cabeçalho, rodapé
Tabelas do Banco de Dados (MYSQL nesse exemplo): Cliente,Estado,Cidade
Figura 3- Diagrama do DB ? 1 -- estado 2 CREATE TABLE IF NOT EXISTS `mydb`.`estado` ( 3 `id` INT(11) NOT NULL AUTO_INCREMENT , `uf` VARCHAR(2) NULL DEFAULT NULL , 4 `nome` VARCHAR(45) NULL DEFAULT NULL , 5 PRIMARY KEY (`id`) ) 6 ENGINE = InnoDB 7 AUTO_INCREMENT = 28 8 DEFAULT CHARACTER SET = utf8 9 COLLATE = utf8_general_ci 10 11-- cidade 12CREATE TABLE IF NOT EXISTS `mydb`.`cidade` ( `id` INT(11) NOT NULL AUTO_INCREMENT , 13 `estado_id` INT(11) NOT NULL , 14 `uf` VARCHAR(2) NULL DEFAULT NULL , 15 `nome` VARCHAR(120) NULL DEFAULT NULL , 16 PRIMARY KEY (`id`) , INDEX `estado_cidade_FK` (`estado_id` ASC) , 17 CONSTRAINT `estado_cidade_FK` 18 FOREIGN KEY (`estado_id` ) 19 REFERENCES `mydb`.`estado` (`id` ) ON DELETE NO ACTION 20 ON UPDATE NO ACTION) 21
22ENGINE = InnoDB 23AUTO_INCREMENT = 9715 DEFAULT CHARACTER SET = utf8 24COLLATE = utf8_general_ci 25 26 27-- cliente 28 29CREATE TABLE IF NOT EXISTS `mydb`.`cliente` ( 30 `id` INT(11) NOT NULL AUTO_INCREMENT , 31 `nome` VARCHAR(255) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , 32 `email` VARCHAR(130) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , 33 `ddd` VARCHAR(3) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NULL DEFAULT 34NULL , 35 `fone` VARCHAR(15) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , 36 `ramal` VARCHAR(6) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NULL DEFAULT NULL , 37 `endereco` VARCHAR(255) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT 38NULL , 39 `numero` VARCHAR(7) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , 40 `complemento` VARCHAR(30) CHARACTER SET 'utf8' COLLATE 'utf8_bin' 41NULL DEFAULT NULL , `bairro` VARCHAR(150) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NULL 42DEFAULT NULL , 43 `cidade_id` INT(11) NOT NULL , 44 `estado_id` INT(11) NOT NULL , 45 `cep` VARCHAR(9) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , `tipo_end` ENUM('Res','Com','Cor') CHARACTER SET 'utf8' COLLATE 46'utf8_bin' NOT NULL DEFAULT 'Res' , 47 `tipo_fone` ENUM('Res','Com','Cel') CHARACTER SET 'utf8' COLLATE 48'utf8_bin' NULL DEFAULT 'Res' , 49 `tipo_cliente` ENUM('pf','pj') CHARACTER SET 'utf8' COLLATE 50'utf8_bin' NULL DEFAULT NULL , `cnpj` VARCHAR(20) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NULL 51DEFAULT NULL , 52 `cpf` VARCHAR(15) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NULL 53DEFAULT NULL , 54 `inscr_estadual` VARCHAR(15) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NULL DEFAULT NULL , 55 `senha` VARCHAR(8) NULL DEFAULT NULL , 56 `ativo` TINYINT(1) NOT NULL DEFAULT '1' , 57 `contato` VARCHAR(150) NULL DEFAULT NULL , 58 PRIMARY KEY (`id`) , 59 INDEX `cidade_cliente_FK` (`cidade_id` ASC) , INDEX `estado_cliente_FK` (`estado_id` ASC) , 60 CONSTRAINT `cidade_cliente_FK` 61 FOREIGN KEY (`cidade_id` ) REFERENCES `mydb`.`cidade` (`id` ) 62 ON DELETE NO ACTION 63 ON UPDATE NO ACTION, 64 CONSTRAINT `estado_cliente_FK` 65 FOREIGN KEY (`estado_id` ) 66 REFERENCES `mydb`.`estado` (`id` ) ON DELETE NO ACTION 67 ON UPDATE NO ACTION) 68 ENGINE = InnoDB 69DEFAULT CHARACTER SET = utf8 70COLLATE = utf8_general_ci 71
Após algumas introduções , vamos ao código : De onde veio este exemplo existem clientes e funcionários.Ambos são pessoas. Assim sendo temos a classe base Pessoa e as classes que estendem Pessoa que são Cliente e Funcionario. /app/model/Pessoa.php ? 1 2 3 // @arquivo = /app/model/Pessoa.php // MVC : model 4 // objeto : Pessoa 5 6 class Pessoa { 7 var $id; 8 var $nome; 9 10 //construtor para poder usar o operador new() 11 public function Pessoa() {} 12 13 public function getId() { 14 return $this->id; } 15 16 public function setId($id) { 17 $this->id = $id; 18 } 19 20 public function getNome() { 21 return $this->nome; } 22 23 public function setNome($nome) { 24 $this->nome = $nome; 25 } 26 27} 28 29
/app/model/Cliente.php ? 1 2 3 4 5 6 7
// // //
@arquivo = /app/model/Cliente.php MVC : model objeto : Cliente
require_once($_SERVER['DOCUMENT_ROOT'] . '/app/model/Pessoa.php'); class Cliente extends Pessoa{ var $email; var $ddd;
var $fone; var $ramal; var $endereco; var $enderecoNum; var $enderecoComplemento; var $bairro; var $cidadeId; var $estadoId; var $cep; var $tipoEndereco; var $tipoFone; var $tipoCliente; var $cnpj; var $cpf; var $inscrEstadual; var $senha; //auxiliar var $cidadeNome; var $estadoNome; public function Cliente() { $this->id=0; } //funcoes automagicas pode fazer assim function __set($param, $value) { $this->$param = $value; } function __get($var) { return $this->$var; } // ou fazer todos os getters e setters public function getEmail() { return $this->email; } public function setEmail($email) { $this->email = $email; } public function getDdd() { return $this->ddd; } public function setDdd($ddd) { $this->ddd = $ddd; } public function getFone() { return $this->fone; } public function setFone($fone) { $this->fone = $fone; } public function getRamal() { return $this->ramal;
} public function setRamal($ramal) { $this->ramal = $ramal; } public function getEndereco() { return $this->endereco; } public function setEndereco($endereco) { $this->endereco = $endereco; } public function getEnderecoNum() { return $this->enderecoNum; } public function setEnderecoNum($enderecoNum) { $this->enderecoNum = $enderecoNum; } public function getEnderecoComplemento() { return $this->enderecoComplemento; } public function setEnderecoComplemento($enderecoComplemento) { $this->enderecoComplemento = $enderecoComplemento; } public function getBairro() { return $this->bairro; } public function setBairro($bairro) { $this->bairro = $bairro; } public function getCidadeId() { return $this->cidadeId; } public function setCidadeId($cidadeId) { $this->cidadeId = $cidadeId; } public function getEstadoId() { return $this->estadoId; } public function setEstadoId($estadoId) { $this->estadoId = $estadoId; } public function getCep() { return $this->cep; }
public function setCep($cep) { $this->cep = $cep; } public function getTipoEndereco() { return $this->tipoEndereco; } public function setTipoEndereco($tipoEndereco) { $this->tipoEndereco = $tipoEndereco; } public function getTipoFone() { return $this->tipoFone; } public function setTipoFone($tipoFone) { $this->tipoFone = $tipoFone; } public function getTipoCliente() { return $this->tipoCliente; } public function setTipoCliente($tipoCliente) { $this->tipoCliente = $tipoCliente; } public function getCnpj() { return $this->cnpj; } public function setCnpj($cnpj) { $this->cnpj = $cnpj; } public function getCpf() { return $this->cpf; } public function setCpf($cpf) { $this->cpf = $cpf; } public function getInscrEstadual() { return $this->inscrEstadual; } public function setInscrEstadual($inscrEstadual) { $this->inscrEstadual = $inscrEstadual; } public function getSenha() { return $this->senha; } public function setSenha($senha) { $this->senha = $senha;
} public function getCidadeNome() { return $this->cidadeNome; } public function setCidadeNome($cidadeNome) { $this->cidadeNome = $cidadeNome; } public function getEstadoNome() { return $this->estadoNome; } public function setEstadoNome($estadoNome) { $this->estadoNome = $estadoNome; }
Agora com a estrutura completa, basta criar a View que mostrará a lista de clientes /pages/listaClientes.php ? 1 2 3 4 5 6 7 8
// // // // //
@arquivo = /pages/listaClientes.php @arquivo = /pages/listaClientes.php MVC : view objeto : Cliente obs : exemplo para o blog
//se o container já não tiver incluido, inclui require_once($_SERVER['DOCUMENT_ROOT'] . '/app/controller/ClienteController.php');
9 $clienteC = new ClienteController(); 10$cache = $clienteC->getListaClientes(); // carrega os registros do array para a view 11$total = count($cache); 12?> 13
e para dar carga nessa tabela troquei o seguinte trecho da linha 11: ? 1 $arrClientes=array(); for ($x=0;$x<=5;$x++){ 2 $cliente = new Cliente(); 3 $cliente->setId($x); 4 $cliente->setNome("Cliente ".$x); $cliente->setEmail("cliente".$x."@exemploblog"); 5