O documento discute conceitos de programação orientada a objetos em PHP, incluindo classes, objetos, herança, métodos estáticos e não estáticos, construtores, destrutores, visibilidade, constantes e exceções.
1. Programação para WEB
Regis Pires Magalhães
regispiresmag@gmail.com
Programação
Orientada a Objetos
em PHP
2. Classes e Objetos
<?php
class Pessoa {
private $nome;
function __construct($nome) {
$this->nome = $nome;
}
function getNome() {
return $this->nome;
}
function setNome($nome) {
$this->nome = $nome;
}
}
$p = new Pessoa('João');
$q = $p;
$p->setNome("Maria");
echo "{$p->getNome()}<br/>";
echo "{$q->getNome()}<br/>";
?>
3. Construtores
No PHP 4, o construtor tinha o mesmo nome da
classe.
No PHP 5, se não for encontrado o __construct(),
ele procurará o construtor com o mesmo nome da
classe.
4. Herança
<?php
require_once('pessoa.php');
class PessoaFisica extends Pessoa {
private $cpf;
function __construct($nome,$cpf) {
parent::__construct($nome);
$this->cpf = $cpf;
}
function getCpf() {
return $this->cpf;
}
function setCpf($cpf) {
$this->cpf = $cpf;
}
}
$pf = new PessoaFisica('Maria','123.456.789-00');
echo "Nome: {$pf->getNome()}<br/>";
echo "CPF: {$pf->getCpf()}<br/>";
?>
5. Sobrescrita de Métodos
<?php
class MinhaClasse {
protected function minhaFuncao() {
echo "MinhaClasse::minhaFuncao()n";
}
}
class OutraClasse extends MinhaClasse {
public function minhaFuncao() {
parent::minhaFuncao();
echo "OutraClasse::minhaFuncao()n";
}
}
$classe = new OutraClasse();
$classe->minhaFuncao();
?>
6. Sobrecarga de Construtores
Em PHP cada classe somente pode ter um único
construtor.
Assim, não há sobrecarga de construtores:
<?php
class Pessoa {
private $nome;
function __construct() {
}
function __construct($nome) {
$this->nome = $nome;
}
}
?>
Fatal error: Cannot redeclare Pessoa::__construct()
7. autoload
Pode-se definir uma função __autoload que é
automaticamente chamada caso seja usada uma
classe que ainda não foi definida.
Isso pode evitar a necessidade de escrever múltiplos
includes ou requires.
<?php
function __autoload($class_name) {
require_once $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
8. autoload
<?php
class MinhaClasse {
function helloWorld() {
echo "Hello, Worldn";
}
}
?>
<?php
function __autoload($class_name) {
require_once($_SERVER["DOCUMENT_ROOT"] .
"/classes/$class_name.php");
}
?>
<?php
require_once "autoload.php";
$obj = new MinhaClasse();
$obj->helloWorld();
?> index.php
autoload.php
MinhaClasse.php
9. Classes e Objetos
<?php
class A {
private $nome;
function __construct($nome) {
$this->nome = $nome;
}
function oi() {
if (isset($this)) {
echo 'Oi, '.$this->nome.'. Este objeto é instância da classe ';
echo get_class($this).'<br/>';
} else {
echo 'Oi, não sei o seu nome, pois o método está sendo ';
echo 'executado estaticamente.<br/>';
}
}
}
class B {
function ola() {
A::oi();
}
}
$a = new A("Maria");
$a->oi();
A::oi();
$b = new B();
$b->ola();
B::ola();
?>
10. Construtores e Destrutores
Construtores pais não são chamados implicitamente pelo
construtor da classe filha.
Para executar o construtor da classe pai, é necessária
uma chamada a parent::__construct() no
construtor da classe filha.
O método destrutor ou finalizador será chamado assim
que todas as referências a um objeto particular forem
removidas ou quando o objeto for explicitamente
destruído através da função unset() ou ainda quando o
programa é finalizado.
Destrutores pais não serão chamados implicitamente.
Para executar o destrutor pai, deve-se fazer uma
chamada explicitamente a parent::__destruct() no
corpo do destrutor.
11. Construtores e Destrutores
<?php
class MinhaClasseDestruivel {
function __construct() {
print "No construtor<br/>";
$this->name = "MinhaClasseDestruivel";
}
function __destruct() {
print "Destruindo $this->name";
}
}
$obj = new MinhaClasseDestruivel();
?>
12. Visibilidade dos membros
<?php
class MinhaClasse {
public $publica = 'Public';
protected $protegida = 'Protected';
private $privada = 'Private';
function imprimeAlo() {
echo $this->publica;
echo $this->protegida;
echo $this->privada;
}
}
$obj = new MinhaClasse();
$obj->imprimeAlo();
echo $obj->publica; // Funciona
echo $obj->protegida; // Erro Fatal
echo $obj->privada; // Erro Fatal
?>
13. Visibilidade dos membros
<?php
class MinhaClasse {
public function __construct() { }
public function meuPublico() { }
protected function meuProtegido() { }
private function meuPrivado() { }
// Se nada for dito, é public
function foo() {
$this->meuPublico();
$this->meuProtegido();
$this->meuPrivado();
}
}
$minhaclasse = new MinhaClasse;
$minhaclasse->foo();
$minhaclasse->meuPublico(); // Funciona
$minhaclasse->meuProtegido(); // Erro Fatal
$minhaclasse->meuPrivado(); // Erro Fatal
?>
14. :: Operador de Resolução de Escopo
Permite acesso a membros estáticos, constantes ou
sobrescritos de uma classe.
<?php
class MinhaClasse {
const VALOR_CONST = 'Um valor constante';
}
$classname = 'MinhaClasse';
echo $classname::VALOR_CONST;
echo MinhaClasse::VALOR_CONST;
?>
15. :: Operador de Resolução de Escopo
<?php
class OutraClasse extends MinhaClasse {
public static $meu_estatico = 'variável estática';
public static function doisPontosDuplo() {
echo parent::VALOR_CONST . "n";
echo self::$meu_estatico . "n";
}
}
$classname = 'OutraClasse';
echo $classname::doisPontosDuplo();
OutraClasse::doisPontosDuplo();
?>
As palavras reservadas self e parent são
usadas para acessar membros de dentro da
definição da classe.
16. Inicializações inválidas
<?php
class SimpleClass {
// declarações de membro inválidas
public $var1 = 'olá '.'mundo';
public $var2 = <<<FIM
olá mundo
FIM;
public $var3 = 1+2;
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
}
?>
Variáveis , membros de classe ou chamada de
função não podem ser usados na inicialização
direta de atributos.
17. Inicializações válidas
<?php
class SimpleClass {
// declarações de membro válidas
public $var6 = myConstant;
public $var7 = self::classConstant;
public $var8 = array(true, false);
}
?>
18. Membros de Classe
<?php
error_reporting(E_STRICT);
class Foo {
public static function umMetodoEstatico() {
echo 'oi<br/>';
}
public function umMetodoNaoEstatico() {
echo 'olá<br/>';
}
}
Foo::umMetodoEstatico();
Foo::umMetodoNaoEstatico();
?>
Chamar métodos não estáticos de maneira
estática gera um aviso de nível E_STRICT.
19. Constantes
Constantes diferem de variáveis normais no não uso
do símbolo $ para declará-las ou usá-las.
<?php
class MinhaClasse {
const constante = 'valor constante';
function mostrarConstante() {
echo self::constante . "<br/>";
}
}
echo MinhaClasse::constante . "<br/>";
$classe = new MinhaClasse();
$classe->mostrarConstante();
?>
20. Classes Abstratas
<?php
abstract class ClasseAbstrata {
abstract protected function pegarValor();
abstract protected function valorComPrefixo( $prefixo );
public function imprimir() {
print $this->pegarValor() . '<br/>';
}
}
class ClasseConcreta1 extends ClasseAbstrata {
protected function pegarValor() {
return "ClasseConcreta1";
}
public function valorComPrefixo( $prefixo ) {
return "{$prefixo}ClasseConcreta1";
}
}
$classe1 = new ClasseConcreta1;
$classe1->imprimir();
echo $classe1->valorComPrefixo('FOO_') . '<br/>';
?>
21. Interfaces
<?php
interface Animal {
public function emiteSom();
}
class Gato implements Animal {
public function emiteSom() {
echo 'Miaaauhh';
}
}
class Cachorro implements Animal {
public function emiteSom() {
echo 'Au, Au';
}
}
$a = new Gato();
$b = new Cachorro();
echo "{$a->emiteSom()}<br/>";
echo "{$b->emiteSom()}<br/>";
?>
22. final
Métodos final NÃO podem ser sobrescritos em classes
que o herdem.
Classes final não podem ser herdadas por outras classes.
O exemplo abaixo não funciona:
<?php
class ClasseBase {
protected $id = 0;
final function getId() {
return $this->id++;
}
}
class ClasseConcreta extends ClasseBase {
function getId() {
return $this->id += 2;
}
}
?>
23. final
O exemplo abaixo também não funciona:
<?php
final class ClasseBase {
// ...
}
class ClasseConcreta extends ClasseBase {
// ...
}
?>
24. O método __toString()
Retorna a representação de um objeto em
forma de string.
<?php
class Pessoa {
private $nome;
function __construct($nome) {
$this->nome = $nome;
}
function __toString() {
return $this->nome;
}
}
$obj = new Pessoa("Maria");
echo $obj;
?>
25. Clonagem de Objetos
Uma cópia de objeto é criada usando o
comando 'clone'. Isso chama o método
__clone() do objeto.
O método __clone() de um objeto não
pode ser executado diretamente.
26. Clonagem de Objetos
<?php
class Fone {
public $numero, $tipo;
public function __construct($numero,$tipo) {
$this->numero = $numero;
$this->tipo = $tipo;
}
}
class Pessoa {
public $nome, $fone;
public function __construct($nome,$num_fone,$tipo_fone) {
$this->nome = $nome;
$this->fone = new Fone($num_fone,$tipo_fone);
}
public function __clone() {
$this->fone = new Fone($this->fone->numero, $this->fone->tipo);
}
}
$p1 = new Pessoa('Maria','8633231845','RES');
$p2 = clone $p1;
echo('<p>Objeto Original:</p>'); print_r($p1);
echo('<p>Objeto Clonado:</p>'); print_r($p2);
$p2->nome = 'João';
$p2->fone->numero = '8699811234';
$p2->fone->tipo = 'CEL';
echo('<p>Objeto Original:</p>'); print_r($p1);
echo('<p>Objeto Clonado:</p>'); print_r($p2);
?>
27. Interceptação
Chamada de métodos e acesso a membros podem
ser interceptados pelos métodos __set, __get e
__call.
__set – intercepta a atribuição de valores a
propriedades do objeto (declaradas ou não).
__get – intercepta requisições de propriedades do
objeto (declaradas ou não).
__call – Intercepta chamadas a métodos. Executado
automaticamente quando um método inexistente for
chamado.
29. Instanciação Dinâmica
<?php
class MinhaClasse {
function exibe($a,$b) {
echo "Parâmetros: $a $b<br/>";
}
}
$classe = 'MinhaClasse';
$metodo = 'exibe';
$obj = new $classe;
call_user_func(array($obj, $metodo),'PHP','WEB');
?>
30. Tratamento de Erros
A forma de manipulação de erro mais simples
é abortar a execução da aplicação através da
função die().
Controlar erros assim é geralmente ruim, pois
abortar a execução do programa
normalmente não é o comportamento
desejado.
31. Geração e Tratamento de Erros
A função trigger_error() gera um erro de um tipo
determinado.
Tipos de erro:
E_USER_ERROR Gera um erro fatal.
E_USER_WARNING Gera uma advertência.
E_USER_NOTICE Gera uma notificação.
A função set_error_handler() define uma função
para tratamento de erros.
32. Geração e Tratamento de Erros
<?php
function trata_erros($tipo_erro,$msg,$arq,$linha) {
echo $msg . '<br/>';
if ($tipo_erro == E_USER_ERROR) {
die;
}
}
set_error_handler('trata_erros');
trigger_error('Ocorreu um erro!!!',E_USER_WARNING);
echo 'Código executado ou não';
?>
33. Exceções
Uma exceção pode ser disparada (throw), ou capturada
(catch).
Código rodeado de um bloco try/catch, permite a captura de
exceções em potencial.
Vários blocos catch podem ser usados para pegar diferentes
classes de exceções.
A execução normal continuará após o último bloco catch
definido na seqüência.
Quando uma exceção é lançada, o fluxo normal de execução é
interrompido e o PHP tentará achar o primeiro bloco catch
correspondente à exceção disparada.
Se uma exceção não for capturada, um Erro Fatal será
lançado com uma mensagem "Uncaught Exception ...", a não
ser que um tratador tenha sido definido com
set_exception_handler().
34. Exceções
Uma exceção é um objeto da classe Exception que
contém os seguintes métodos:
getMessage() - Retorna a mensagem de erro.
getCode() - Retorna o código de erro.
getFile() - Retorna o arquivo no qual ocorreu o erro.
getLine() - Retorna a linha na qual ocorreu o erro.
getTrace() - Retorna um array com as ações até o erro.
getTraceAsString() - Retorna as ações em forma de
string.
36. Tratador de Exceções
A função set_exception_handler() define uma função
de tratamento de exceção padrão se uma exceção não
for capturada em um bloco try/catch.
A execução não parará depois que a função de
tratamento for chamada.
<?php
function trata_excecoes($ex) {
echo $ex->getMessage(),'<br/>';
}
set_exception_handler('trata_excecoes');
throw new Exception('Exceção ocorreu!!!');
echo 'Código não executado';
?>
37. Comparação de Objetos
Operador de comparação (==)
Objetos são iguais se possuírem o mesmo
conteúdo e forem instâncias da mesma classe.
Operador de identidade (===)
Objetos são idênticos se referenciam a mesma
instância de uma mesma classe.
39. Comparação de Tipo
<?php
class Pessoa { }
class PessoaFisica extends Pessoa { }
$p1 = new PessoaFisica();
var_dump($p1 instanceof Pessoa);
var_dump($p1 instanceof PessoaFisica);
var_dump($p1 instanceof PessoaJuridica);
?>
instanceof é usado para determinar se um
objeto é de uma determinada classe: