Desenvolvimento - PHP

Mapeamento objeto relacional VO em PHP

Veja neste artigo como mapear uma tabela (Mapeamento objeto-relacional) do banco dados com PHP, ou seja, como criar um VO (Value Objects) - representação de uma entidade de negócios - em PHP.

por Gregory Monteiro



Nesse artigo vou mostrar como mapear uma tabela do banco dados com php, ou seja, vamos criar um VO (Value Object) em PHP.

O propósito de um VO (Value Object) é de representar uma entidade de negócios. Um VO é uma classe de mapeamento de dados que espelha a entidade que existe no banco de dados. Um VO mais complexo pode incorporar outras funcionalidades em seus métodos. Por exemplo, um VO pode ter um método que transforma seus dados em um nó XML ou um VO pode ser capaz de ler seus dados a partir de um HTML. A única coisa que o VO não tem que se preocupar é o banco de dados. A finalidade principal do VO é armazenar os dados que entram e sai da base de dados.

Nesse exemplo estou usando o banco de dados MySQL.

Vamos primeiramente criar um banco de dados chamado “teste”. Ver Listagem 1

Listagem 1: Código para criar um banco de dados no MySQL query

create database teste

Em seguida vamos criar uma tabela que será usada no nosso mapeamento. O nome da nossa tabela será “usuarios”. Essa tabela terá um id e os campos nome, login e senha. Ver Listagem 2.

Listagem 2: Código para criar a tabela usuarios no MySQL query

CREATE TABLE teste.usuarios (
 id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
 nome VARCHAR(45) NOT NULL,
 login VARCHAR(45) NOT NULL,
 senha VARCHAR(45) NOT NULL
)

Vamos inserir uns valores na tabela de usuários para podermos testar a classe que iremos criar. Ver Listagem 3.

Listagem 3: Inserindo dados na tabela Usuarios

INSERT INTO teste.usuarios (nome,login,senha) VALUES('nome1','login1','senha1');
INSERT INTO teste.usuarios (nome,login,senha) VALUES('nome2','login2','senha2');
INSERT INTO teste.usuarios (nome,login,senha) VALUES('nome3','login3','senha3');
INSERT INTO teste.usuarios (nome,login,senha) VALUES('nome4','login4','senha4');

Agora vamos criar a estrutura da classe que irá mapear essa tabela de usuarios. Para isso vamos criar um arquivo chamado usuariosVO.php e criar a nossa classe usuariosVO. Ver Listagem 4.

Listagem 4: Estrutura da classe usuariosVO

<?php
class usuariosVO{
}
?>

Vamos então adicionar os métodos padrões para as classes de mapeamento, que são o __construct, __clone e __destruct. Ver Listagem 5.

Os métodos __construct e __destruct.são padrões do php e são responsáveis por construir e destruir a instancia da nossa classe.

O método __clone evita que nossa classe seja clonada.

Saiba mais sobre esses métodos nos links http://www.php.net/manual/pt_BR/language.oop5.decon.php e http://www.php.net/manual/pt_BR/language.oop5.cloning.php.

Listagem 5: Classe usuarios com os métodos __construct, __clone e __destruct

<?php
class usuariosVO{
	/*Método construtor da classe*/
	public function __construct(){}
	
	/*Evita que a classe seja clonada*/
	private function __clone(){}
	
	/*Método destrutor da classe*/
	public function __destruct() {
		foreach ($this as $key => $value) { 
			unset($this->$key); 
        }
		foreach(array_keys(get_defined_vars()) as $var) {
			unset(${"$var"});
		}
		unset($var);
	}
}
?>

Na Listagem 5 o método __destruct remove da memória todas as variáveis que foram definidas pela nossa classe.

Agora vamos criar as variáveis privadas que receberão os valores da nossa tabela usuarios junto com seus métodos get e set, terminando assim a nossa classe de mapeamento de objeto relacional ou VO. Ver Listagem 6.

Listagem 6: Classe usuarios com os métodos get e set e as variáveis privadas

<?php
class usuariosVO{
	/*Método construtor da classe*/
	public function __construct(){}
	
	/*Evita que a classe seja clonada*/
	private function __clone(){}
	
	/*Método destrutor da classe*/
	public function __destruct() {
		foreach ($this as $key => $value) { 
			unset($this->$key); 
        }
		foreach(array_keys(get_defined_vars()) as $var) {
			unset(${"$var"});
		}
		unset($var);
	}
	
	/*Variáveis privadas que receberão os dados*/
	private $id = 0;
	private $nome = "";
	private $login = "";
	private $senha = "";
	
	/*Metodos get e set que trazem o conteudo da variável privada desejada*/
	public function getId(){
		return $this->id;
	}
	public function setId($id){
		$this->id = intval($id);
	}
	
	public function getNome(){
		return $this->nome;
	}
	public function setNome($nome){
		$this->nome = $nome;
	}
	
	public function getLogin(){
		return $this->login;
	}
	public function setLogin($login){
		$this->login = $login;
	}
	
	public function getSenha(){
		return $this->senha;
	}
	public function setSenha($senha){
		$this->senha = $senha;
	}
}
?>

Vamos ver uma aplicação prática de como usar a classe usuariosVO.

Obs.: como o objetivo desse exemplo é mostrar como usar os métodos da classe que criamos, não vou me ater ao desenvolvimento de um Data Acess Object (DAO) e de uma classe para conectar no banco de dados.

Veja esses artigos para saber mais sobre um Data Acess Object (DAO) e uma classe de conexão com o banco de dados: Trabalhando com Data Access Object (DAO) em PHP e PDO em PHP Orientado a Objetos.

Na Listagem 7 vemos como usar a classe usuariosVO para receber os dados da tabela usuarios. Nesta listagem fiz um simples exemplo de como usar o PDO para retornar os dados de um registro da tabela.

Estou usando o método fetchAll (http://php.net/manual/pt_BR/pdostatement.fetchall.php) para retornar os dados em forma de objetos e, após isso setando, esses dados na classe de mapeamento através dos métodos set que criamos.

Por fim, uso os métodos get para retornar esses dados e mostrá-los na tela.

Listagem 7: Código de exemplo para testar a classe usuariosVO retornando um registro apenas

<?php
class ClassAutoloader{
	public function __construct(){
		spl_autoload_register(array($this, 'loader'));
	}
	private function loader($className){
		include_once $className . '.php';
	}
}
$autoloader = new ClassAutoloader();

try
{
	/*tentando se conectar ao banco de dados MySQL*/
	$conexao = new PDO("mysql:host=localhost;port=3306;dbname=teste", "root", "123");
}
catch (PDOException $i)
{
	/*se houver exceção, exibe*/
	die("Erro: <code>" . $i->getMessage() . "</code>");
}

$sql = "SELECT * FROM usuarios WHERE id = ?";
$params = array(1);

$query=$conexao->prepare($sql);
$query->execute($params);
$rs = $query->fetchAll(PDO::FETCH_OBJ) or die(print_r($query->errorInfo(), true));

/*instancia da classe usuariosVO*/
$usuariosVO = new usuariosVO();

/*usando os métodos set da classe usuariosVO*/
$usuariosVO->setId($rs[0]->id);
$usuariosVO->setNome($rs[0]->nome);
$usuariosVO->setLogin($rs[0]->login);
$usuariosVO->setSenha($rs[0]->senha);

/*usando os métodos get da classe usuariosVO*/
echo $usuariosVO->getId() . "<br>\n";
echo $usuariosVO->getNome() . "<br>\n";
echo $usuariosVO->getLogin() . "<br>\n";
echo $usuariosVO->getSenha() . "<br>\n";

$conexao = null;
?>

Como vemos na Listagem 7, estou usando a classe ClassAutoloader para chamar automaticamente as classes que serão usadas no exemplo.

Essa classe usa a função spl_autoload_register implementada no PHP 5.1.2. Para saber mais acesse http://www.php.net/manual/pt_BR/function.spl-autoload-register.php.

Veja o resultado na Figura 1.

Dados do exemplo para testar a classe usuariosVO retornando um registro apenas

Figura 1: Dados do exemplo para testar a classe usuariosVO retornando um registro apenas

Na Listagem 8 modifiquei o exemplo fazendo o método fetchAl associar automaticamente os registros da tabela usuarios a classe usuariosVO. Por fim faço um loop com os métodos get para retornar esses dados e mostrá-los na tela.

Listagem 8: Código de exemplo para testar a classe usuariosVO retornando todos os registros da tabela

<?php
class ClassAutoloader{
	public function __construct(){
		spl_autoload_register(array($this, 'loader'));
	}
	private function loader($className){
		include_once $className . '.php';
	}
}
$autoloader = new ClassAutoloader();

try
{
	/*tentando se conectar ao banco de dados MySQL*/
	$conexao = new PDO("mysql:host=localhost;port=3306;dbname=teste", "root", "123");
}
catch (PDOException $i)
{
	/*se houver exceção, exibe*/
	die("Erro: <code>" . $i->getMessage() . "</code>");
}

$sql = "SELECT * FROM usuarios";

$query=$conexao->prepare($sql);
$query->execute();
$rs = $query->fetchAll(PDO::FETCH_CLASS,"usuariosVO") or die(print_r($query->errorInfo(), true));

foreach ($rs as $key => $row){
	/*usando os métodos get da classe usuariosVO*/
	echo $row->getId() . "<br>\n";
	echo $row->getNome() . "<br>\n";
	echo $row->getLogin() . "<br>\n";
	echo $row->getSenha() . "<br><br>\n\n";
}

$conexao = null;
?>

Veja o resultado na Figura 2.

Dados do exemplo ao testar a classe usuariosVO retornando todos os registros da tabela

Figura 2: Dados do exemplo para testar a classe usuariosVO retornando todos os registros da tabela

Fico por aqui e bons códigos.

Gregory Monteiro

Gregory Monteiro - Programador/administrador dos sites da DevMedia. Formado em sistemas de informação. Certificados SEO pela mestreseo e ietv. Certificado CMMI pela FIOCRUZ. Curso de web developer pela microcamp. Administrador de redes. Conhecimentos em C#, VB.NET, ASP, PHP, JSP, HTML, XHTML, HTML5, Ajax, CSS3, jQuery, JavaScript, SQL Server, MySQL, Firebird, IIS 6/7, NGINX, Linux, WPF