+2

Novos Features no PHP5

criado por Rodrigo Rodrigues em 16/07/2004 11:29am
Uma visão geral do PHP5 com Orientação a Objetos, dando exemplos do uso dos novos features disponíveis.

Para baixar o PHP5, visite a URL abaixo:

http://www.php.net/downloads.php#v5

1) Especificadores de Acesso dos métodos e variáveis
Descrição: Específica o acesso de controle na classe evitando erros lógicos, existem 3 acessos possíveis(public, protected, private) caso não coloque nenhum entende-se como "public".
Public = Pode ser acessado por qualquer classe.
Protected = Poder ser acessado somente por quem extende sua classe.
Private = Poder ser acessado somente por sua classe.
Exemplo:

<?php
class EspecificaAcesso
{
    public $varPublic = "Variável pública<br>";
    protected $varProtected = "Variável Protegida<br>";
    private $varPrivate = "Variável Privada<br>";

    public function getPublic()
    {
        return $this->varPublic;
    }

    protected function getProtected()
    {
        return $this->varProtected;
    }

    private function getPrivate()
    {
        return $this->varPrivate;
    }

    public function getMetodoPrivate()
    {
        return EspecificaAcesso::getPrivate();
    }
}

$especificaAcesso = new EspecificaAcesso();
echo $especificaAcesso->getPublic();
echo $especificaAcesso->getMetodoPrivate();

// Descomentando a linha abaixo dará um Fatal Error porq o método tem acesso Privado(private).
// echo $especificaAcesso->getPrivate();
// Descomentando a linha abaixo dará um Fatal Error porq o método tem acesso Protegido(protected).
// echo $especificaAcesso->getProtected();

class UsandoProtegido extends EspecificaAcesso
{
    function getProtegido()
    {
        return parent::getProtected(); // Se você chamar um método privado"getPrivate()" dará um Fatal Error.
    }
}

$usandoProtegido = new UsandoProtegido();
echo $usandoProtegido->getProtegido();
?>

2) Métodos e variáveis estáticas
Descrição: Quando declarar static no método ou variável poderá usalo sem precisar instânciar sua classe.
Exemplo:

<?php
class Estatica
{
    static $varStatic = "Variável Estática<br>";

    static function getStatic()
    {
        return Estatica::$varStatic;
    }
}

// Ou chamando a variável diretamente "Estatica::$varStatic".
echo Estatica::getStatic();
?>

3) Métodos finais
Descrição: Quando declarar final no método seu valor inicial não poderá ser alterado, o engraçado é que se declarar nas variáveis da Fatal Error, que coisa não :).
Exemplo:

<?php
class ClasseFinal
{
    final function getFinal()
    {
        echo "Método Final";
    }
}

$classeFinal = new ClasseFinal();
$classeFinal->getFinal();
?>

4) Métodos construtor/destrutor
Descrição: Método __construct() é executado quando instância a classe e o __destruct() é executado na destruição do objeto, caso sua classe herda outra automaticamente irá sobrepor os 2 métodos, para usalos precisa chamar diretamente "parent::__construct()".
Exemplo:

<?php
class ContrutorDestrutor
{
    private $varMethod;

    function __construct()
    {
        $this->varMethod = "Construtor()";
        echo "Método {$this->varMethod}<br>";
    }

    function __destruct()
    {
        $this->varMethod = "Destrutor()";
        echo "Método {$this->varMethod}<br>";
    }
}

$contrutorDestrutor = new ContrutorDestrutor();
unset($contrutorDestrutor);

class ContrutorDestrutorFilho extends ContrutorDestrutor
{
    function __construct()
    {
        parent::__construct();
        echo "Método Filho Construtor<br>";
    }

    function __destruct()
    {
        parent::__destruct();
        echo "Método Filho Destrutor<br>";
    }
}

echo "<br>";
$contrutorDestrutorFilho = new ContrutorDestrutorFilho();
?>

5) Constantes da Classe
Descrição: Constante é alguma informação da classe que pode ser acessada diretamente, logicamente é o mesmo que static.
Exemplo:

<?php
class Constante
{
    const constante = "Minha Constante";
}
echo Constante::constante;
?>

6) Clonando objetos
Descrição: O método __clone() define o comportamento do objeto clonado.
Exemplo:

<?php
class ClasseClonando
{
    public $varClone;

    function __construct()
    {
        $this->varClone = "Php5";
    }

    function __clone()
    {
        $this->varClone = "Php5 Clone";
    }
}

$classeClonando = new ClasseClonando();
$cloneClasseClonando = clone $classeClonando;
echo $classeClonando->varClone . "<br>" . $cloneClasseClonando->varClone;
?>

7) Verificando se a instância é da Classe específica
Descrição: Comando instanceof verifica se a instância passada é da Classe específica retornando um boolean(true ou false).
Exemplo:

<?php
class TesteInstanceOf
{
}

class ClasseInstanceOf
{
    function __construct($obj)
    {
        if ($obj instanceof TesteInstanceOf) {
            echo "Objeto da classe(TesteInstanceOf)";
        } else {
            echo "Não é um objeto da classe(TesteInstanceOf)";
        }
    }
}

$testeInstanceOf = new TesteInstanceOf();
$classeInstanceOf = new ClasseInstanceOf($testeInstanceOf);
?>

8) Classes Abstratas
Descrição: Declaramos uma Classe abstrata quando um conjunto de métodos será utilizado em diferentes classes.
A classe abstrata não pode ser instânciada diretamente para usala precisa a extendela e criar todos os métodos abstratos com seus acessos.
Exemplo:

<?php
abstract class Abstrata
{
    public abstract function setNome($nome);
    public abstract function getNome();
}

class ClasseAbstrata extends Abstrata
{
    private $nome;

    public function setNome($newNome)
    {
        $this->nome = $newNome;
    }

    public function getNome()
    {
        return $this->nome;
    }
}

$classeAbstrata = new ClasseAbstrata();
$classeAbstrata->setNome("Php5");
echo $classeAbstrata->getNome();
?>

9) Implementando Interfaces
Descrição: Interfaces tem quase o mesmo conceito da abstração, com a diferênça que você pode implementar 'n' interfaces.
Exemplo:

<?php
interface IPessoa
{
    public function setNome($nome);
    public function getNome();
}

interface IPessoaFisica
{
    public function setCpf($cpf);
    public function getCpf();
}

interface IPessoaJuridica
{
    public function setCnpj($cnpj);
    public function getCnpj();
}

class ClassePessoa implements IPessoa, IPessoaFisica, IPessoaJuridica
{
    function __construct($nome, $cpf, $cnpj)
    {
        ClassePessoa::setNome($nome);
        ClassePessoa::setCpf($cpf);
        ClassePessoa::setCnpj($cnpj);
    }

    /* Métodos Set */
    public function setNome($nome)
    {
        $this->nome = $nome;
    }

    public function setCpf($cpf)
    {
        $this->cpf = $cpf;
    }

    public function setCnpj($cnpj)
    {
        $this->cnpj = $cnpj;
    }

    /* Métodos Get */
    public function getNome()
    {
        return $this->nome;
    }

    public function getCpf()
    {
        return $this->cpf;
    }

    public function getCnpj()
    {
        return $this->cnpj;
    }

    function __destruct()
    {
        echo ClassePessoa::getNome()."<br>".ClassePessoa::getCpf()."<br>".ClassePessoa::getCnpj();
    }
}

$classePessoa = new ClassePessoa("Rodrigo", "324.541.588-98", "6545.2101/0001");
?>

10) Tratamento de erros(lógicos)
Descrição: Caso aconteça algum erro lógico em RunTime(tempo de execução) da para tratalo de outras maneiras, o código a ser executado fica dentro do "try" e acontecendo algum erro vai para o "catch".
Exemplo:

<?php
class BusinessException extends Exception
{
    function __construct($msg)
    {
        // Vai para a função construtora do Exception.
        parent::__construct($msg);
    }
}

class Excecao
{
    function __construct($nome)
    {
        try {
            if ($nome == "") {
                throw new BusinessException("Nome não pode ser em branco.");
            } elseif(strlen($nome) < 5) {
                throw new BusinessException("Nome precisa ter no mínimo 5 letras.");
            } elseif(strtolower($nome) == "corinthians") {
                throw new BusinessException("Corinthians campeão ou não tu moras no meu coração.");
            } else {
                throw new BusinessException("Paramêtro inválido.");
            }
        } catch (BusinessException $businessException) {
            echo $businessException->getMessage();
        }
    }
}

$excecao = new Excecao("Corinthians");
?>

11) Pattern Singleton
Descrição: Garante que terá somente um único objeto de uma classe, um exemplo bom para usalo seria na comunicação com o banco de dados.
Exemplo:

<?php
class Singleton
{
    private static $instance = null;

    public static function getInstance()
    {
        if (Singleton::$instance == null) {
            Singleton::$instance = new Singleton();
        }
        return Singleton::$instance;
    }
}

$objA = Singleton::getInstance();
$objB = Singleton::getInstance();
if ($objA == $objB) {
    echo "Instância única";
} else {
    echo "Instâncias diferentes";
}
?>

12) Pattern Factory
Descrição: É uma classe onde centraliza a criação de objetos sendo assim não precisa instâncialos diretamente nas classes.
Exemplo:

<?php
abstract class AbstractFactory
{
    private $nome;
    private $rendaMensal;

    function __construct($nome, $rendaMensal)
    {
        $this->setNome($nome);
        $this->setRendaMensal($rendaMensal);
    }

    public function setNome($newNome)
    {
        $this->nome = $newNome;
    }

    public function setRendaMensal($newRendaMensal)
    {
        $this->rendaMensal = $newRendaMensal;
    }

    public function getNome()
    {
        return $this->nome;
    }

    public function getRendaMensal()
    {
        return $this->rendaMensal;
    }

    public abstract function analisarCredito(); // Boolean
    public abstract function getCategoria(); // String
}

class ClientePadrao extends AbstractFactory
{
    function __construct($nome, $rendaMensal)
    {
        parent::__construct($nome, $rendaMensal);
    }

    // Foi declarada no AbstractFactory
    public function analisarCredito()
    {
        return true;
    }

    // Foi declarada no AbstractFactory
    public function getCategoria()
    {
        return "Cliente Padrão";
    }
}

class ClienteRisco extends AbstractFactory
{
    function __construct($nome, $rendaMensal)
    {
        parent::__construct($nome, $rendaMensal);
    }

    // Foi declarada no AbstractFactory
    public function analisarCredito() 
    {
        return false;
    }

    // Foi declarada no AbstractFactory
    public function getCategoria()
    {
        return "Cliente Risco";
    }
}

class ClienteSeguro extends AbstractFactory
{
    function __construct($nome, $rendaMensal)
    {
        parent::__construct($nome, $rendaMensal);
    }

    // Foi declarada no AbstractFactory
    public function analisarCredito()
    {
        return true;
    }

    // Foi declarada no AbstractFactory
    public function getCategoria()
    {
        return "Cliente com alta credibilidade";
    }
}

class SingletonFactory
{
    private static $rendaMedia = 500;
    private static $rendaBaixa = 240;
    private static $instance = null; 

    public static function getCliente($nome, $rendaMensal)
    {
        if ($rendaMensal <= SingletonFactory::$rendaBaixa) {
            SingletonFactory::$instance = new ClienteRisco($nome, $rendaMensal);
        } elseif ($rendaMensal > SingletonFactory::$rendaBaixa and $rendaMensal <= SingletonFactory::$rendaMedia) {
            SingletonFactory::$instance = new ClientePadrao($nome, $rendaMensal);
        } else {
            SingletonFactory::$instance = new ClienteSeguro($nome, $rendaMensal);
        }

        $clienteAprovacao = "reprovado";
        if (SingletonFactory::$instance->analisarCredito()) {
            $clienteAprovacao = "aprovado";
        }

        echo "Cliente = ".SingletonFactory::$instance->getNome()."<br>";
        echo "Categoria = ".SingletonFactory::$instance->getCategoria()."<br>";
        echo "Crédito = ".$clienteAprovacao;
        echo "<hr>";
    }
}

SingletonFactory::getCliente("Rodrigo", 1977);
SingletonFactory::getCliente("Corinthians", 350);
SingletonFactory::getCliente("John", 220);
?>

Caso algo esteja errado favor me avise.

Referências:
http://www.tarcisiolopes.com
http://www.zend.com

Sem mais,
Rodrigo Rodrigues

Comentários:

Mostrando 1 - 10 de 14 comentários
Dam disse:
Bom artigo.
20/11/2008 4:26am (~15 anos atrás)

Rodrigo, no item 5 você fala que constantes são o mesmo que variáveis static, o que é um erro. As variáveis static podem ser acessadas sem a necessidade de instanciação e os seus valores podem ser alterados a qualquer momento, diferente das constantes, onde o valor atribuído na inicialização não pode ser alterado.
30/03/2005 10:15pm (~19 anos atrás)

Pô eu conhecia try catch do .NET da Micro$oft não sabia que o php dava esse suporte, porém procurei na documentação do php.net e não encontrei nada.
02/03/2005 8:36am (~19 anos atrás)

Gustavo Dutra disse:
Como eu disse no título é um detalhe. Quando usamos membros ou métodos de uma classe estáticos, não que seria errado, mas o mais certo seria usar

<?php

self::$membro; // Para variáveis estáticas na classe.

self::metodo(); // Para métodos estáticos

parent::$membro; // Para variáveis da classe pai chamadas pela classe filha.

e

parent::metodo(); // Para métodos da classe pai chamados pela classe filha.

Mas, como oop5 ainda suporta o oop anterior, não ocorrerá erros se caso houver um Classe::metodo(); ou o mesmo com um membro.

Vocês podem ver isso no primeiro cometário de http://br2.php.net/manual/pt_BR/language.oop5.static.php
01/03/2005 1:39pm (~19 anos atrás)

Gustavo Dutra disse:
Sim, vai mudar. Mas até a versão 5.0.3 ela está inauteráda. Você pode encontrar mais sobre em http://br2.php.net/manual/pt_BR/function.pdo-construct.php
01/03/2005 1:33pm (~19 anos atrás)

Fiquei surpreso em ver que o modelo OOP do PHP 5 sintaticamente é muito parecido com o Java.
25/10/2004 9:12pm (~19 anos atrás)


O acesso ao banco de dados continua da mesma forma com php5? Ouvi dizer que talvez mudaria com a nova versão...
21/07/2004 6:09am (~20 anos atrás)

Caro Rodrigo,

Esses pequenos atalhos nos auxiliam muito num mundo em que o tempo é cada vez mais escasso.

Essas dicas expressas são ótimas.
20/07/2004 12:09pm (~20 anos atrás)

Marlon, veja o trecho do Changelog do PHP5 (http://www.php.net/ChangeLog-5.php#5.0.0):
---------------------------------
Improved the streams support: (Wez, Sara, Ilia)
Improved performance of readfile(), fpassthru() and some internal streams operations under Win32.
stream_socket_client() - similar to fsockopen(), but more powerful.
stream_socket_server() - Creates a server socket.
stream_socket_accept() - Accept a client connection.
stream_socket_get_name() - Get local or remote name of socket.
stream_copy_to_stream()
stream_get_line() - Reads either the specified number of bytes or until the ending string is found.
Added context property to userspace streams object.
Added generic crypto interface for streams (supports dynamic loading of OpenSSL)
Added lightweight streaming input abstraction to the Zend Engine scanners to provide uniform support for include()'ing data from PHP streams across all platforms.
Added 'string.base64' stream filter.
Renamed stream_register_wrapper() to stream_wrapper_register().
Added "ftp://" wrapper support to opendir(), stat() and unlink().
Added context options 'method', 'header' and 'content' for "http://" fopen wrapper
-------------------------------------

Falow!
19/07/2004 10:40pm (~20 anos atrás)

E ei Rodrigo gostei desse metodo que vc tentou passar p/ nos usuários foi bem aproveitado por mim.
Valeu........
19/07/2004 5:01pm (~20 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)