segunda-feira, 18 de março de 2013

Introdução a Orientação a Objetos no PHP - Parte 4

Construtor e Destrutor de Classes

O construtor  __construct(), é uma função definida na classe e que é executada sempre que o objeto é criado (isto é, sempre que a classe é instanciada). No PHP a função __construct() é implícita, ela esta subentendida quando usamos new(). A função __construct() pode ser construída de forma que aceite parâmetros na sua definição. 
    public function __construct($n = "", $i="")
    {
        $this->setNome($n);
        $this->t;setIdade($i);
    }
Isto é útil quando chamamos new() com parâmetros assim economizamos linhas de código pois não precisamos chamar os métodos set() para definir os valores dos atributos do objeto. Como no exemplo abaixo.
<?php
     if(!empty($_GET))
     {
         $n = $_GET['nome'];
         $i = $_GET['idade'];
         try 
         {
             $cliente = new Cliente($n, $i);
             //$cliente->setNome($nome);
             //$cliente->setIdade($idade);
             echo $cliente->getNome() . ", salvo com sucesso.";
             echo $cliente->getIdade() . " anos de idade.";
         }
         catch (Exception $e)
         {
             echo $e->getMessage();
         }
     }
?>
O destrutor da classe, a função __destruct() não recebe nenhum paràmetro, é executado sempre que o objeto for destruído, seja de forma explicita ou implicitamente (por exemplo, no final do script que utiliza a classe).
    public function __destruct() 
    {
        echo "O objeto " . $this->getNome() . " foi destruído.";
    }
Classes que estendem outras classes, ou seja, subclasses o construtor precisa ser chamado de forma explícita, mas sobre isso falarei mais adiante, nas aulas futuras. Disponibilizo o código completo da classe abaixo.
<?php
/**
 * Classe Cliente
 *
 * @author Luiz Carlos
 */
class Cliente {
    //Atributos
    public $nome;
    protected $idade;
    //Métodos
    
    public function __construct($n = "", $i = "")
    {
        $this->setNome($n);
        $this->setIdade($i);
    }

    public function __destruct() 
    {
        echo "O objeto " . $this->getNome() . " foi destruído.";
    }

    public function setNome($nome)
    {
        $this->nome = $nome;
    }
    
    public function setIdade($idade)
    {
        if($idade > 130)
        {
//            exit();
            throw new Exception("Idade inválida!");
        }
        else
        {
            $this->idade = $idade;
        }
    }

    public function getNome()
    {
        return $this->nome;
    }
    
    public function getIdade()
    {
        return $this->idade;
    }
}
?>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html" charset="UTF-8"/>
        <title>Classe Cliente</title>
    </head>
    <body>
        <?php
            if(!empty($_GET))
            {
                $n = $_GET['nome'];
                $i = $_GET['idade'];
                try 
                {
                    $cliente = new Cliente($n, $i);
                    //$cliente->setNome($nome);
                    //$cliente->setIdade($idade);
                    echo $cliente->getNome() . ", salvo com sucesso.";
                    echo $cliente->getIdade() . " anos de idade.";
                }
                catch (Exception $e)
                {
                    echo $e->getMessage();
                }
            }
        ?>
        <form name="fcliente" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
            <label for="nome">Nome</label>
            <input name="nome" type="text" maxlength="30" size="30"/>
            <label for="idade">Idade</label>
            <input name="idade" type="text" maxlength="3" size="3" />
            <input value="Salvar" type="submit">
        </form>
    </body>        
</html>
Segue vídeo-aula...

Até a próxima!

quinta-feira, 7 de março de 2013

Introdução a Orientação a Objetos no PHP - parte 3

Ola! Nesta vídeo aula, vou explicar os motivos para não utilizar atributos públicos e mostrar a forma mais segura para trabalhar com objetos. Primeiro vamos alterar a visibilidade do atributo idade para protected.
class Cliente {
    //Atributos
    public $nome;
    protected $idade;
Agora vamos comentar os métodos e fazer a atribuição dos atributos de forma direta, o código deve ficar igual abaixo:
<?php
	if(!empty($_GET))
	{
		$nome = $_GET['nome'];
		$idade = $_GET['idade'];
        $cliente = new Cliente();
//                    $cliente->setNome($nome);
//                    $cliente->setIdade($idade);
//                    echo $cliente->getNome() . ", salvo com sucesso.<>";
//                    echo $cliente->getIdade() . " anos de idade.";
		$cliente->nome = $nome;
		$cliente->idade = $idade;
		echo $cliente->nome . ", salvo com sucesso<>";
		echo $cliente->idade . " anos é a idade do cliente!";
	}
?>
Salvando as alterações e acessando a página, nos é retornado um erro fatal como este:
Fatal error: Cannot access protected property Cliente::$idade in /opt/lampp/htdocs/php_oo/Cliente.php on line 58
Este erro diz que não podemos acessar a propriedade protegida do atributo idade do objeto Cliente, ou seja, não podemos acessar de forma direta o atributo, devemos utilizar os métodos para isso. Vamos realizar algumas alterações em nosso método setIdade, nosso método deve ficar como abaixo:
public function setIdade($idade)
{
	if($idade > 130)
	{
//            exit();
		throw new Exception("Idade inválida!");
	}
	else
	{
		$this->idade = $idade;
	}
}

Vamos alterar também o script PHP que trata o retorno do formulário, deve ficar assim:
<?php
	if(!empty($_GET))
	{
		$nome = $_GET['nome'];
		$idade = $_GET['idade'];
		$cliente = new Cliente();
		$cliente->setNome($nome);
		$cliente->setIdade($idade);
		echo $cliente->getNome() . ", salvo com sucesso.";
		echo $cliente->getIdade() . " anos de idade.";
	}
?>
Agora estamos utilizando um novo recurso em nosso código, o comando throw, ele dispara um erro fatal da classe Exception com a mensagem "Idade inválida!"
Fatal error: Uncaught exception 'Exception' with message 'Idade inválida!' in /opt/lampp/htdocs/php_oo/Cliente.php:22 Stack trace: #0 /opt/lampp/htdocs/php_oo/Cliente.php(54): Cliente->setIdade('132') #1 {main} thrown in /opt/lampp/htdocs/php_oo/Cliente.php on line 22
A mensagem acima informa que o erro foi pego (Uncaugth) e além da mensagem ele exibe qual o método ocasionou o erro Cliente->setIdade('132') e o número da linha que gerou o erro, no caso a linha 22. Para que o sistema não encerre com o erro fatal precisamos tratar esta exceção alterando o script que recebe o formulário. Ele ficará conforme abaixo:
<?php
	if(!empty($_GET))
	{
		$nome = $_GET['nome'];
		$idade = $_GET['idade'];
		try
		{
			$cliente = new Cliente();
			$cliente->setNome($nome);
			$cliente->setIdade($idade);
			echo $cliente->getNome() . ", salvo com sucesso. ";
			echo $cliente->getIdade() . " anos de idade.";
		}
		catch(Exception $e)
		{
			echo $e->getMessage();
		}
	}
?>
O comando try tentará executar o bloco, se um erro ocorrer o script passa para o segundo bloco catch (pegar). Lembre-se que a Exception é uma classe! Capturada a exceção pelo bloco catch, ele instancia um objeto da classe Exception chamado $e e executa seu método getMessage() que exibe a mensagem passada anteriormente pelo comando throw.
Segue o código completo do script utilizado no exemplo:
<?php
/**
 * Classe Cliente
 *
 * @author Luiz Carlos
 */
class Cliente {
    //Atributos
    public $nome;
    protected $idade;
    //Métodos
    public function setNome($nome)
    {
        $this->nome = $nome;
    }
    
    public function setIdade($idade)
    {
        if($idade > 130)
        {
            throw new Exception("Idade inválida!");
        }
        else
        {
            $this->idade = $idade;
        }
    }

    public function getNome()
    {
        return $this->nome;
    }
    
    public function getIdade()
    {
        return $this->idade;
    }
}
?>
<html>
    
        
        Classe Cliente
    
    <body>
<?php
	if(!empty($_GET))
	{
		$nome = $_GET['nome'];
		$idade = $_GET['idade'];
		try
		{
			$cliente = new Cliente();
			$cliente->setNome($nome);
			$cliente->setIdade($idade);
			echo $cliente->getNome() . ", salvo com sucesso.
";
			echo $cliente->getIdade() . " anos de idade.";
		}
		catch(Exception $e)
		{
			echo $e->getMessage();
		}
	}
?>
        
</body> </html>
Aproveito para convidar quem quiser se associar ao meu blog, será bem vindo!
Obrigado. Espero que esta aula ajude. Até a próxima!

segunda-feira, 4 de março de 2013

Introdução a Orientação a Objeto no PHP - parte 2

Nesta continuação da aula anterior exemplifico os motivos para não utilizar atributos públicos e atribuição de valores diretamente aos objetos.


Quando definimos um atributo público no caso de nossa classe Cliente, a qual possui um atributo nome com visibilidade public, devemos ficar atentos para que atribuição de valores indesejados não ocorra!
<?php
/**
 * Classe Cliente
 *
 * @author Luiz Carlos
 */
class Cliente {
    //Atributos
    public $nome;
}
?>
Vanmos comentar os métodos setNome e getNome da classe Cliente.
    //Métodos
//    public function setNome($nome)
//    {
//        $this->nome = $nome;
//    }
//   
//    public function getNome()
//    {
//        return $this->nome;
//    }
Podemos atribuir e recuperar valores acessando diretamente o objeto.
    if(!empty($_GET))
    {     
        $nome = $_GET['nome'];
        $cliente = new Cliente();
//        echo $cliente->nome . ", salvo com sucesso<>";
//        echo $cliente->idade . " anos é a idade do cliente!";
        $cliente->nome = $nome;
        echo $cliente->nome . ", salvo com sucesso!";
    }
Nosso script irá funcionar. Agora vamos adicionar um novo atributo idade.
class Cliente {
    //Atributos
    public $nome;
    public $idade;
}
No formulário adicione mais um label e um input para idade, o formulário deve ser igual a este:
<form name="fcliente" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
    <label for="nome">Nome</label>
    <input name="nome" type="text" maxlength="30" size="30"/>
    <label for="idade">Idade</label>
    <input name="idade" type="text" maxlength="3" size="3" />
    <input value="Salvar" type="submit">
</form>
Por último alteramos o nosso script responsável por tratar o formulário:
    if(!empty($_GET))
    {      
        $cliente = new Cliente();
        $nome = $_GET['nome'];
        $idade = $_GET['idade'];
//        echo $cliente->nome . ", salvo com sucesso<>";
//        echo $cliente->idade . " anos é a idade do cliente!";
        $cliente->nome = $nome;
        $cliente->idade = $idade;
        echo $cliente->nome . ", salvo com sucesso!<>";
        echo $cliente->idade . " é a idade no cliente!";
    }
Quando atribuímos valores diretamente ao atributo do objeto, qualquer valor pode ser aceito! Coisas estranhas e mensagens indesejadas como um cliente com 175 anos de idade, pode ocorrer! Para resolver esta anomalia, devemos usar métodos que tratam os dados antes de atribuir os valores aos objetos, como segue:
    public function setIdade($idade)
    {
        if($idade > 130)
        {
            exit();
        }
        else
        {
            $this->idade = $idade;
        }
    }
No método setIdade, testamos o parâmetro recebido executando a condicional if(se) for maior que 130, executa a função exit() do PHP, else (senão) grava o valor no atributo do objeto. Segue o código completo do exemplo...
<?php
/**
 * Classe Cliente
 *
 * @author Luiz Carlos
 */
class Cliente {
    //Atributos
    public $nome;
    protected $idade;
    //Métodos
    public function setNome($nome)
    {
        $this->nome = $nome;
    }
    
    public function setIdade($idade)
    {
        if($idade > 130)
        {
           exit();
        }
        else
        {
            $this->idade = $idade;
        }
    }

    public function getNome()
    {
        return $this->nome;
    }
    
    public function getIdade()
    {
        return $this->idade;
    }
}
?>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html" charset="UTF-8"/>
        <title>Classe Cliente</title>
    </head>
    <body>
        <?php
            if(!empty($_GET))
            {
                $nome = $_GET['nome'];
                $idade = $_GET['idade'];
                $cliente = new Cliente();
                $cliente->setNome($nome);
                $cliente->setIdade($idade);
                echo $cliente->getNome() . ", salvo com sucesso.<>";
                echo $cliente->getIdade() . " anos de idade.";
            }
        ?>
        <form name="fcliente" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
            <label for="nome">Nome</label>
            <input name="nome" type="text" maxlength="30" size="30"/>
            <label for="idade">Idade</label>
            <input name="idade" type="text" maxlength="3" size="3" />
            <input value="Salvar" type="submit">
        </form>
    </body>        
</html>
Obrigado. Bom estudo!