Feeds:
Posts
Comentários

Em um sistema de informação orientado à objetos continuamente precisamos que um determinado objeto de uma classe, ao executar um de seus métodos, informe a outros objetos esta ação.

Para exemplificar, imagine que uma empresa possui um sistema de controle de produtos e estoque orientado à objetos e necessita que toda vez que o preço de algum de seus produtos mude os representantes sejam informados. Assim sendo, toda vez que o atributo preço de algum produto seja alterado, o produto terá que informar automaticamente todos representantes que seu preço mudou.Para resolver este tipo de problema podemos usar o pattern Observer. Este pattern consiste em termos um objeto OBSERVADO e objetos OBSERVADORES. O objeto observado deverá ter a capacidade de agregar observadores e de notificá-los de alguma mudança.

O PHP5 nativamente possui as interfaces SplObserver e SplSubject. A interface SplSubject serve para implementarmos classes cujos objetos serão observados por outros, por isto esta interface quando implementada  nos obriga a criar os métodos públicos attach (para inserir um observador a coleção de observadores), detach (para retirar um observador da coleção) e o mais importante, notify (usado para informar todos observadores presentes na coleção de alguma coisa). Já a interface SplObserver serve para implementarmos observadores. Esta nos obriga a criar o método update (que recebe o objeto observado como parâmetro) disparado pelo objeto observado.

Segue abaixo as interfaces presentes na biblioteca SPL nativa no PHP5:

interface SplObserver
{
    function 
update(SplSubject $subject);
}

interface SplSubject
{
    function 
attach(SplObserver $observer);
    function 
detach(SplObserver $observer);
    function 
notify();
}

Agora vamos resolver um problema real como exemplo de uso do pattern Observer. Neste exemplo teremos uma classe Editora que terá como capacidade principal lançar um livro. Como uma Editora tem clientes esta classe também deverá fornecer a seus objetos a capacidade de agregar clientes para que estes sejam informados automáticamente caso um novo livro seja lançado. Portanto os objetos da classe Editora poderão ser observados pelos clientes (seus observadores). Para isto  a classe Editora implementará a interface SplSubject e a classe Cliente implementará SplObserver.

Segue o código:

<?php
/**
 * Classe responsável pela criação de editoras
 * @author           Lucas Soler
 * @copyright        Copyright 2009 Lucas Soler
 * @package          www
 * @subpackage       www
 * @version          1.0
 */ 
class Editora implements SplSubject{
    
/**
     * Coleção de observadores da editora
     * @access private
     * @name $observadores
     */ 
    
private $observadores;
    
/**
     * Recebe o nome do último livro lançado
     * @access private
     * @name $livroLancado
     */ 
    
private $livroLancado;
    
/**
     * Recebe o nome da editora
     * @access private
     * @name $nome
     */ 
    
private $nome;
    
/**
     * Cria uma editora atribuindo um nome a ela e iniciando a coleção de observadores
     * @access public 
     * @param string $nome Nome da editora
     * @return void
     */
    
public function __construct($nome){
        
$this->observadores = array();
        
$this->nome $nome;
    }
    
/**
     * Método mágico __set. Atribui valor a qualquer atributo
     * @access public 
     * @param string $nm Nome do atributo
     * @param mixed $value Valor para o atributo
     * @return void
     */
    
public function __set($nm,$value)
    {
        
$this->$nm $value;
    }

    /**
     * Método mágico __get. Retorna o valor de qualquer atributo
     * @access public 
     * @param string $nm Nome do atributo
     * @return mixed O valor do atributo passado como parâmetro (pode ser de qualquer tipo)
     */
    
public function __get($nm)
    {
        return 
$this->$nm;
    }
    
    
/**
     * Acrescenta um observador à editora
     * @access public 
     * @param SplObserver $observador Objeto observador a ser inserido na coleção
     * @return void
     */
    
public function attach(SplObserver $observador){
        
$this->observadores[] = $observador;
    }

    /**
     * Retira um observador da editora
     * @access public 
     * @param SplObserver $observador Objeto observador a ser retirado da coleção
     * @return void
     */
    
public function detach(SplObserver $observador){
        
$newObservadores = array();
        foreach(
$this->observadores as $key => $ob){
            if(
$ob !== $observador){
                
$newObservadores[] = $ob;
            }
        }
        
$this->observadores $newObservadores;
    }
 
    
/**
     * Dispara o método "update" de todos observadores 
     * @access public 
     * @return void
     */
    
public function notify(){
        foreach(
$this->observadores as $ob){
            
$ob->update($this);
        }
    }

    /**
     * Lança um livro e informa todos observadores sobre o lançamento
     * @access public 
     * @param string $nomeLivro Nome do livro lançado
     * @return void
     */
    
public function lancarLivro($nomeLivro){
        
$this->livroLancado $nomeLivro;
        
$this->notify();
    }

}

/**
 * Classe responsável pela criação de clientes
 * @author           Lucas Soler
 * @copyright        Copyright 2009 Lucas Soler
 * @package          www
 * @subpackage       www
 * @version          1.0
 */ 
class Cliente implements SplObserver{
    
/**
     * Recebe o nome do cliente
     * @access private
     * @name $nome
     */ 
    
private $nome;/**
     * Cria um cliente atribuindo a ele um nome
     * @access public 
     * @param string $nome Nome do cliente
     * @return void
     */
    
public function __construct($nome){
        
$this->nome $nome;
    }
    
    
/**
     * Método mágico __get. Retorna o valor de qualquer atributo
     * @access public 
     * @param string $nm Nome do atributo
     * @return mixed O valor do atributo passado como parâmetro (pode ser de qualquer tipo)
     */
    
public function __get($nm)
    {
        return 
$this->$nm;
    }
    
    
/**
     * Recebe o objeto observado quando este lança um livro e informa características do lançamento
     * @access public 
     * @param SplSubject $objObservado Objeto observado
     * @return void
     */
    
public function update(SplSubject $objObservado){
        echo 
"A editora ".$objObservado->__get("nome")." comunicou a ".$this->nome." em ".date("d/m/Y")." às ".date("H:i:s")." que o livro ".$objObservado->livroLancado." foi lançado<br/>";    
    }

}

$editora = new Editora("LucasTec");
$lucas = new Cliente("Lucas Soler");
$suemi = new Cliente("Suemi Shimizu");
$tiago = new Cliente("Tiago Soler");
//Inserindo os clientes como observadores da editora
$editora->attach($lucas);
$editora->attach($suemi);
$editora->attach($tiago);
//Caso tenha que retirar um observador da coleção este é o código
//$editora->detach($suemi);
//Editora lança livro e informa os observadores sobre o lançamento
$editora->lancarLivro("Lucas Soler - TI Orientada à Prática");

?>

Programação Orientada a Objetos (POO)

Este post tem como objetivo explicar claramente o que é o paradigma de programação orientada a objetos (POO). Outros posts explicarão conceitos agregados a este, como o de classes, objetos, herança, polimorfismo etc.

Para começar vamos revisar o modelo de programação procedural, para que assim possamos ter uma base para comparação entre este modelo e a POO. Um sistema de informação que faz uso da programação procedural tem como princípio a criação e execução de procedimentos ou funções. Neste paradigma podemos criar certas rotinas para resolver um determinado problema. Estas rotinas, ou funções, são compostas de um número limitado de comandos para a solução do problema. Por exemplo, para calcular o fatorial de um número podemos criar uma função para fazer isto. A função receberá um número (parâmetro) e terá que nos fornecer um resultado, neste caso o número fatorial do parâmetro passado. Após criá-la é só chamar a função no nosso código passando um número como parâmetro. Em PHP, uma linguagem procedural mas que pode ser Orientada a Objetos, isto ficaria assim:

<?php
    
function factorial($num) {
        if((
$num == 0)||($num == 1)) {
            return 
1;
        }
        else {
            return 
$num*factorial($num-1);
        }
    }
    echo 
factorial(7); 
    

?>

Pronto, desta forma isolamos a rotina para solucionar o problema de cálculo de fatorial e poderemos chamar esta rotina sempre que precisarmos. Esta é exatamente e idéia desta forma de programar, isolar soluções para problemas em funções podendo assim reutilizá-las. Isto nos poupa muito tempo e trabalho repetitivo além de deixar o código mais legível.

Porém atualmente outro paradigma de programação vem sendo amplamente adotado, forma esta que possui muitas facilidades e benefícios. É a Programação Orientada a Objetos. Esta baseia-se na criação e interação entre objetos. O que a POO tenta fazer é aproximar a solução de um problema computacional ao mundo real. Assim sendo, usar este paradigma facilitará a construção de sistemas de informação. Para entendê-lo mais a fundo vamos ver como funcionam os sistemas naturais. Por exemplo, o sistema respiratório. Vários órgãos(objetos) fazem parte dele e é a interação entre estes órgãos que possiblita o funcionamento deste sistema. Cada órgão é responsável por uma ou várias funções, e para realizar seu trabalho eles se “comunicam” trocando mensagens e até mesmo interagem com órgãos de outros sistemas de nosso organismo, permitindo assim que vivamos. No mundo da POO é isto que temos, objetos executando suas funções e trocando mensagens entre si, para que juntos formem um sistema computacional. Obviamente tais objetos não são “reais” mas sim são estruturas computacionais armazenadas na memória do computador ou em outro meio (Ex.: Bancos de dados). Agora que sabemos o que é POO, vamos conhecer mais a fundo outros conceitos envolvidos nisto, como o conceito de classe e objeto que abordaremos no próximo post.

Não é incomum ao desenvolvermos um sistema de informação encontrarmos várias vezes o mesmo problema de programação. A solução que muitos encontram é copiar e colar código. Em um projeto grande o que acaba acontecendo é que no MESMO sistema o MESMO problema é programado de forma diferente por cada programador. Isto realmente não é uma boa solução. Por isto alguns programadores enfrentam um problemão quando precisam alterar ou continuar um projeto feito por outro que não seguiu padrão nenhum. Uma solução muito melhor e largamente aceita é o uso de Design Patterns (Padrões de Projeto). Um Design Pattern é um padrão para solução de um problema comum amplamente testado e aceito. Por isto, sempre que possível, é aconselhado o uso destes padrões, pois isto facilitará a manutenção e legibilidade de nosso código. Outra vantagem é que outros programadores (se conhecerem Padrões de Projeto) poderão continuar nossos trabalhos com facilidade já que conhecem a solução que adotamos. Assim sendo toda a equipe de desenvolvimento será beneficiada. Por esta razão os Design Patterns são considerados formas de descrever as melhores práticas em programação*.

* Design Patterns não se referem apenas a padrões a serem usados em sistemas de informação. Outras áreas das ciências utilizam este conceito

O próximo passo é conhecermos e implementarmos um design pattern como exemplo.

Factory

Segundo a documentação do PHP “o padrão Factory permite a instanciação de objetos em tempo de execução. É chamado de Factory uma vez que é responsável por ‘produzir’ um objeto. O Factory parametrizado recebe como argumento o nome da classe para instanciar.”
Vamos agora implementar nosso próprio factory. Para isto criaremos uma classe chamada ‘FactoryPattern’ com apenas um método estático – factory. Este método receberá como parâmetro o nome da classe para instanciar e retornará um novo objeto desta classe OU uma Exception caso o arquivo desta classe não seja encontrado. Criaremos assim um padrão factory exatamente aos moldes da solução proposta pela documentação do PHP.

Na solução que produzi utilizei a classe RecursiveDirectoryIterator. A finalidade disto é explicada no próprio código da classe ‘FactoryPattern’. Caso você queira saber mais sobre DirectoryIterator clique aqui.

Obs.: Não foi incluída no código a classe “Cliente” usada no exemplo

<?php
/**
 * Classe responsável pela criação dos objetos do sistema
 * @author           Lucas Soler
 * @copyright        Copyright 2009 Lucas Soler
 * @package          www
 * @subpackage       www
 * @version          1.0
 */ 
class FactoryPattern
{
    
/**
     * Cria um objeto da classe passada como parâmetro varrendo 
     * o diretório informado recursivamente em busca do arquivo da classe
     * @access public 
     * @param string $class Classe do objeto a ser instanciado
     * @exception A classe informada não foi localizada
     * @return object Retorna um objeto genérico
     */
    
public static function factory($classe)
    {
        
//Nome do diretório onde estão as classes ou/e subdiretórios de classes do sistema. No nosso caso será o diretório "classes"
        
$diretorio ".";
        
$arqs = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($diretorio));
        foreach(
$arqs as $name => $arq){
            if(
$arq->isFile()){
                
/* Se o arquivo corrente for o que armazena a classe 
                   do parâmetro um objeto desta classe é instanciado e retornado */
                
if($arq->getFilename() == $classe.".php" || $arq->getFilename() == $classe.".class.php"){
                    include_once 
$arq->getPathname();    
                    return new 
$classe;
                }
            }
        }
        
// Caso a classe não exista uma exceção é lançada 
        
throw new Exception ("A classe {$classe} não foi encontrada!");
    }

}

$cliente FactoryPattern::factory("Cliente");
echo 
$cliente->__get("nome");
?>

Neste post mostrarei como transformar um objeto em XML com o auxílio da API para reflexão de objetos que o PHP5 nos fornece.

Primeiramente, vamos entender para que serve uma classe de reflexão. Uma classe assim nos permite obter informações de classes, interfaces, métodos etc. Por exemplo, podemos conhecer todos atributos de um objeto, os valores deles, qual a sua visibilidade (public, private ou protected) dentre outras informações.  Além disto conseguimos obter também seus métodos e invocá-los. Sabendo disto vamos utilizar agora a classe ReflectionClass para conseguirmos uma reflexão de nossos objetos e assim gerar conteúdo XML contendo os dados deles. Vamos criar uma classe “Xml” com um método chamado toXml(). Todas as outras classes criadas herdarão os comportamentos de “Xml”, e assim os objetos instanciados apartir delas poderão se transformar em conteúdo XML. Para poder ser convertido para XML o objeto terá que ter o método mágico __get.

Uma das aplicações que vejo para isto é a persistência de objetos. Em determinado momento geralmente precisaremos manter nossos objetos em um meio externo a aplicação. O método mais usado para isto é guardá-los em um banco de dados. Mas as vezes temos uma aplicação tão pequena que nem precisamos de um banco de dados. Assim sendo podemos persistir nossas informações em um arquivo XML. Usando o método toXml() isto ficará mais fácil!

<?php
/**
 * A classe XML serve para criar e manipular XML
 * @author           Lucas Soler
 * @copyright        Copyright 2009 Lucas Soler
 * @package          www
 * @subpackage       www
 * @version          1.0
 */ 
class Xml{
    
/**
     * Transforma um objeto em XML
     * @access public 
     * @return string O objeto em formato XML
     */
    
public function toXml(){
        
$obj $this;
        
//A classe ReflectionClass permite fazer a engenharia-reversa da classe 
        
$classe = new ReflectionClass(get_class($obj));
        
$metodoGet $classe->getMethod("__get");
        
$atributos $classe->getProperties();
        
$xml .= "\t<".$classe->getName().">\n";    
        foreach(
$atributos as $att){
            
$xml .= "\t\t<".$att->getName().">";
            
$xml .= $metodoGet->invoke($obj,$att->getName());
            
$xml .= "</".$att->getName().">\n";
        }
        
$xml .= "\t</".$classe->getName().">\n";    
        return 
$xml;
    }
}

/**
 * Esta classe é responsável pela criação de uma pessoa
 * @author           Lucas Soler
 * @copyright        Copyright 2009 Lucas Soler
 * @package          www
 * @subpackage       www
 * @version          1.0
 */ 
class Pessoa extends Xml{
   
/**
     * Recebe o nome da pessoa
     * @access private
     * @name $nome
     */ 
    
protected $nome;
    
/**
     * Recebe a data de nascimento da pessoa
     * @access private
     * @name $dtNascimento
     */ 
    
protected $dtNascimento;
    
/**
     * Recebe o peso da pessoa
     * @access private
     * @name $peso
     */ 
    
protected $peso;
    
/**
     * Recebe a altura da pessoa
     * @access private
     * @name $altura
     */ 
    
protected $altura;
    
    
/**
     * Cria a pessoa atribuindo a ela um nome, uma data de nascimento, um peso e uma altura
     * @access public 
     * @param string $nome Nome do cachorro
     * @param string $peso Peso do cachorro
     * @return void
     */
    
function __construct($nome,$dtNascimento,$peso,$altura){
        
$this->__set("nome",$nome);
        
$this->__set("dtNascimento",$dtNascimento);
        
$this->__set("peso",$peso);
        
$this->__set("altura",$altura);
    }

    /**
     * Método mágico __set. Atribui valor a qualquer atributo
     * @access public 
     * @param string $nm Nome do atributo
     * @param mixed $value Valor para o atributo
     * @return void
     */
    
public function __set($nm,$value)
    {
        
$this->$nm $value;
    }

    /**
     * Método mágico __get. Retorna o valor de qualquer atributo
     * @access public 
     * @param string $nm Nome do atributo
     * @return mixed O valor do atributo passado como parâmetro (pode ser de qualquer tipo)
     */
    
public function __get($nm)
    {
        return 
$this->$nm;
    }

}

try {

    $pessoas = array();
    
/* Se o arquivo pessoas.xml já existir, todas pessoas 
       persistidas são carregadas na memória e guardadas na coleção $pessoas */
    
if(is_file("pessoas.xml")){
        
//Transforma o arquivo XML em uma coleção de objetos
        
$xml simplexml_load_file("pessoas.xml");
        
//Percorre a coleção de objetos já persistidos e cria uma coleção de objetos "Pessoa".
        
foreach($xml as $pessoa){
            
$pessoas["$pessoa->nome"] = new Pessoa($pessoa->nome,$pessoa->dtNascimento,$pessoa->peso,$pessoa->altura);
        }
    }
    
//Criação de uma nova coleção ($novasPessoas) caso as pessoas indicadas ainda não existam no XML
    
if(!$pessoas['Lucas Soler']){
        
$lucas = new Pessoa("Lucas Soler","16/02/1986","79","1.77");
        
$novasPessoas[] = $lucas;
    }
    if(!
$pessoas['Suemi Shimizu']){
        
$suemi = new Pessoa("Suemi Shimizu","20/08/1987","54","1.73");
        
$novasPessoas[] = $suemi;
    }
    
//Caso existam novas pessoas o arquivo onde estão persistidos os objetos é reescrito
    
if(!empty($novasPessoas)){
        
$fp fopen("pessoas.xml","w+"); 
        
$pessoas array_merge($pessoas,$novasPessoas);
        
fwrite($fp,"<?xml version='1.0' encoding='ISO-8859-1'?>\n");
        
fwrite($fp,"<Pessoas>\n");
        foreach(
$pessoas as $pessoa){
            
fwrite($fp,$pessoa->toXml());
        }    
        
fwrite($fp,"</Pessoas>");
    }
    
} catch(
Exception $exception) {
    echo 
$exception->getMessage();
}

?>

Quando ainda estávamos na era do PHP4 e criávamos um código para percorrer um diretório, nosso produto final ficava mais ou menos assim:

<?php
//Abre o diretório do arquivo atual
$pasta = opendir(getcwd());
//Cria um loop para percorrer todos os registros de um diretório
while (($arquivo = readdir($pasta)) !== false) {
    echo
$arquivo."<br />";
}
//Fecha o diretório
closedir($pasta);

?>

Já no PHP5 contamos com o advento dos Iterators, objetos que nos permitem percorrer uma cadeia de dados(esta definição não serve para a interface Iterator). Uma das classes nativas do PHP5 que implementa a interface Iterator é DirectoryIterator. A classe DirectoryIterator nos possibilita percorrer um diretório tratando o arquivo da iteração corrente como um objeto e podemos assim por exemplo obter o nome de um arquivo, seu tamanho e tipo através de métodos.  Abaixo segue um exemplo de iteração de um diretório por meio de um objeto proveniente de DirectoryIterator. A cada iteração mostraremos o nome e o tipo do arquivo corrente.

foreach(new DirectoryIterator(getcwd()) as $arq){
    echo
$arq->getFilename().' - '.$arq->getType()."<br/>";
}

Uma solução com certeza mais elegante!

Este primeiro post servirá apenas para uma aquecimento e mostrará o método que sempre vou usar em meus exemplos. Sempre definirei um problema claramente e em seguida mostrarei uma solução possível (digo “uma” porque cada programador pode ter uma solução diferente para o mesmo problema) usando a programação orientada ao objeto(POO). Com o passar do tempo vou inserir no blog fundamentos de programação e de POO para que mesmo os iniciantes nestas técnicas possam tirar proveito do material aqui disponibilizado.

Primeira classe

Para começar vamos resolver um pequeno problema comum nos programas que registram datas em bancos de dados. Nossos usuários brasileiros digitam datas no formato brasileiro(dd/mm/aaaa) ou nossas interfaces com o usuário tratam as datas para que fiquem neste formato. Mas o formato padrão para armazenarmos esta informação em um BD é o formato americano (aaaa-mm-dd). Os frameworks para PHP possuem API para tratar isto, mas como só vamos exercitar algumas técnicas de POO e queremos neste caso resolver nossos próprios problemas vamos implementar uma classe chamada Data que nos proverá uma API para validarmos e convertermos uma data. Poderemos assim  tanto converter uma data para formato banco quanto transformar uma vinda do banco para formato brasileiro (embora isto seja possível com SQL). Outra funcionalidade interessante da classe é que ela validará a data gerando exceções caso necessário. 

<?php
/**
 * Esta classe é responsável pela validação e conversão de uma data
 * @author           Lucas Soler
 * @copyright        Copyright 2009 Lucas Soler
 * @package          www
 * @subpackage       www
 * @version          1.0
 */ 
class Data{
    
/**
     * Recebe a data a ser validada ou convertida
     * @access private
     * @name $data
     */ 
    
private $data;
    
/**
     * Recebe o tipo do formato da data recebida. Pode ser 'br'(brasileiro) ou 'usa' (americano)
     * @access private
     * @name $tipo
     */ 
    
private $tipo;
    
/**
     * Array que recebe a posição do dia,mês e ano dos formatos 'br' e 'usa' no atributo $data 
     * @access private
     * @name $formatos
     */ 
    
private $formatos;
    
    
/**
     * Atribui um valor inicial na criação do objeto Data para os atributos $data e $tipo
     * @access public 
     * @param string $data Data a ser manipulada ou validada
     * @param string $tipo Tipo do formato da data recebida. Pode ser 'br'(brasileiro) ou 'usa' (americano)
     * @return void
     */
    
public function __construct($data,$tipo){
        
$this->data $data;
        
$this->tipo $tipo;
        
$this->formatos = array("br" => array("dia" => array(0,2),
                                              
"mes" => array(3,2),
                                              
"ano" => array(6,4)),
                                
"usa" => array("dia" => array(8,2),
                                               
"mes" => array(5,2),
                                               
"ano" => array(0,4)));
    }
    
    
/**
     * Verifica se o atributo $data contém uma data válida
     * @access public 
     * @return boolean
     */
    
public function ehValida(){
        if(
strlen($this->data) == 10){
            
$arrayData $this->dataParaFormato();
            if(
$this->verificaDia($arrayData["dia"]) && 
               
$this->verificaMes($arrayData["mes"]) && 
               
$this->verificaAno($arrayData["ano"]))
                return 
true;
        }
        throw new 
Exception("Data inválida para o formato '{$this->tipo}'");
    }
/**
     * Converte o atributo $data para o formato americano yyyy-mm-dd
     * @access public 
     * @return string Data convertida para formato americano
     */
    
public function dataParaUsa(){
        if(
$this->ehValida()){
            
$arrayData $this->dataParaFormato();
            return 
"{$arrayData[ano]}-{$arrayData[mes]}-{$arrayData[dia]}";
        }
    }
    
    
/**
     * Converte o atributo $data para o formato brasileiro dd/mm/yyyy
     * @access public 
     * @return string Data convertida para formato brasileiro
     */
    
public function dataParaBr(){
        if(
$this->ehValida()){
            
$arrayData $this->dataParaFormato();
            return 
"{$arrayData[dia]}/{$arrayData[mes]}/{$arrayData[ano]}";
        }
    }
    
    
/**
     * Converte o atributo $data do formato string para um array com dia, mes e ano
     * @access private 
     * @return array Data convertida para array
     */
    
private function dataParaFormato(){
        
$formato $this->formatos[$this->tipo];
        if(
is_array($formato)){
            
$ano substr($this->data$formato[ano][0],$formato[ano][1]);
            
$mes substr($this->data$formato[mes][0],$formato[mes][1]);
            
$dia substr($this->data$formato[dia][0],$formato[dia][1]);
            return array(
"dia" => $dia,"mes" => $mes,"ano" => $ano);
        }
        throw new 
Exception("Formato inexistente para o tipo '{$this->tipo}'");
    }
/**
     * Verifica se o parâmetro $dia é um dia válido
     * @access private 
     * @param string $dia Dia a ser validado
     * @return boolean
     */
    
private function verificaDia($dia){
        
$dia = (int) $dia;
        if((
is_int($dia)) && ($dia && $dia <= 31))
            return 
true;
        return 
false;
    }
    
/**
     * Verifica se o parâmetro $mes é um mês válido
     * @access private 
     * @param string $mes Mês a ser validado
     * @return boolean
     */
    
private function verificaMes($mes){
        
$mes = (int) $mes;
        if((
is_int($mes)) && ($mes && $mes <= 12))
            return 
true;
        return 
false;
    }
    
/**
     * Verifica se o parâmetro $ano é um ano válido
     * @access private 
     * @param string $ano Ano a ser validado
     * @return boolean
     */
    
private function verificaAno($ano){
        
$ano = (int) $ano;
        if((
is_int($ano)) && (strlen($ano) == 4))
            return 
true;
        return 
false;
    }

}

$data = new Data("2009-04-19","usa");
try{
    echo $data->dataParaBr();
}catch(
Exception $e){
    echo 
$e->getMessage();
}

?>