PROGRAMAÇÃO ORIENTADA A OBJETO EM PHP O PHP através da versão 5, veio desenvolvido com suporte a programação orientada a objetos. O que significa isso? Que a partir da versão 5 é possível criar bibliotecas de scripts e armazená-las em classes e criar objetos e instanciar seus métodos e atributos. Mas antes de tudo vamos explicar o que é classe, o que é método, o que é atributo e o que é objeto. 5.1 CLASSE: Classe é uma biblioteca com um conjunto de scripts que podem ser acessados através de outras classes e através de objetos criados através de uma instância dela. Exemplo: class basics{ conjunto de scripts a serem instanciados em um objeto 5.2 MÉTODOS: Métodos são os scripts que compõem uma classe, na verdade para ficar bem fácil de entender, um método é uma função dentro de uma classe, porém para ela estar dentro de uma classe devo dar permissão de acesso a esta função, por isso ela deixa de ser função e passa a ser método. Exemplo: A função abaixo: function porcentagem($x,$y){ $valor = floatval($x * (1+$y)); return $valor; Para virar método e la deve estar dentro de uma classe. Ficaria assim class basics{ public function porcentagem($x,$y){ $valor = floatval($x * (1+$y)); return $valor; 5.3 ATRIBUTOS: Atributos são características de um objeto. Na realidade são variáveis internas da 1
classe, por exemplo na classe basics, temos antes de declarar os métodos, declarar os atributos nele usados como parâmetros. class basics{ public $x; public $y; public function porcentagem($x,$y){ $valor = floatval($x * (1+$y)); return $valor; 5.4 OBJETO Objeto é uma instância de uma classe. Ao criar um objeto posso acessar seus métodos e seus atributos. Um exemplo. Salvo a classe basics num arquivo como basics.php E num arquivo chamado objeto, faço o script abaixo. <?php include "basics.php"; $objeto = new basics(); echo $objeto->porcentagem(200,10);?> Eu preciso usar o símbolo está para -> 2
CONCEITOS AVANÇADOS DE PROGRAMAÇÃO ORIENTADA A OBJETO EM PHP 6.1. CLASSES SIMPLES O PHP é uma linguagem de programação que nos permite a construção de aplicativos com orientação a objeto. Para criarmos uma classe em PHP, temos que saber o que é uma VARIÁVEL (capitulo 2), uma FUNÇÃO (capitulo 4). Segue abaixo as referências que devemos ter na construção de uma classe com o PHP. palavra-chave class indica uma declaração de classe, delimitada por chaves. Dentro da classe podemos definir atributos (variáveis) e métodos (funções) que formam o estado e o comportamento do objeto. Um método com o mesmo nome da classe é o construtor do objeto sendo executado sempre que uma instância for criada. classe deve utilizar a variável $this ou self para referenciar seus próprios métodos e atributos definição da classe deve estar disponível no script ou página PHP que utiliza a classe (comandos include ou require). Um objeto da classe deve ser instanciado pelo operador new. O operador -> permite referenciarmos atributos e métodos do objeto Exercício para tratar datas, estudo de caso. <?php 1 class basics { public $mes; 2 public $data; public $valor; public $semana; public $caracter; public $url; public $string; public $msg; 6 public function formata_data_banco($data) {//converte data dd/mm/aaaa para aaaa-mm-dd 7 if ($data == "") return null; 8 $corrige = explode("/", $data); 9 $corrige = $corrige[2]."-".$corrige[1]."-".$corrige[0]; 10 return $corrige; 11 12 public function formata_data_br($data) {//converte aaaa-mm-dd para dd/mm/aaaa 3
13 if ($data == "") return ""; 14 $corrige = explode("-",$data); 15 $corrige = $corrige[2]."/".$corrige[1]."/".$corrige[0]; 16 return $corrige; 17 18 public function formata_dollar($valor) {//converte valor de U$ para R$ 19 $valor = str_replace('.','',$valor); 20 $valor = str_replace(',','.',$valor); 21 if(empty($valor)) return "0.00"; 22 return $valor; 23 24 public static function formata_real($valor) {//converte valor de U$ para R$ $valor = str_replace('.',',',$valor); if(empty($valor)) return "0,00"; return $valor; 25 public function nome_mes($mes) { //converte mês em número para o nome em pt 26 $arr = array('janeiro','fevereiro','março','abril','maio','junho','julho','agosto','set embro','outubro','novembro','dezembro'); 27 return $arr[$mes]; 28 29 public function semana($semana) {//converte o dia da semana em num para extenso em pt 30 $arr = array('domingo','segunda-feira','terça-feira','quarta-feira','quinta- Feira','Sexta-Feira','Sábado'); 31 return $arr[$semana]; 32 33 public function caracteres($string,$caracter){ 34 $str = substr($string,0,$caracter)."..."; 35 return $str; 36 37 public function data_hoje(){ 38 return date("y")."-".date("m")."-".date("d"); 39 40 public function horario(){ 41 return date("h")."-".date("i")."-".date("s"); 42 43 public function redireciona($url){ 44?> 45 <script> 46 location.href="<?= $url?>"; 47 </script> 48 <? 49 50 public function redireciona_msg($url,$msg){ 51?> 52 <script> 53 location.href="<?= $url?>"; 54 alert("<?= $msg?>"); 55 </script> 56 <? 4
57 58?> O arquivo acima apresenta métodos para tratar data, dias da semana e converter valor de dólar para real. Segue explicação linha a linha. Na linha 1 criamos a classe Das linhas 2 a 5 instanciamos os atributos que serão usados nos métodos abaixo. Das linhas 6 a 11 criamos o método que formata_ data_banco que irá converter a data de dd/mm/aaaa para aaaa-mm-dd que é aceita para inserir registros no banco de dados. Na linha 7 temos um if de uma linha só checando se a variável data é vazia, se for a classe devolve a variável nula, sem valor senão ela faz as linhas abaixo. Na linha 8, a função interna do PHP explode irá quebrar a string em array através da delimitação do símbolo / e criar em 3 pedaços. Repare que na lógica se eu quebrar a data de hoje em 3 pedaços, no pedaço 1 estará o dia, no dois o mês e o terceiro o ano, porém array o índice começa no 0, por isso que a string nova a ser formada com os pedaços seria: $corrige[2]."-".$corrige[1]."-".$corrige[0]; O scritp das linhas 12 a 17 são idênticos aos das linhas 6 a 11, porém o que de limita a data agora é o símbolo (-). 12 public function formata_data_br($data) {//converte aaaa-mm-dd para dd/mm/aaaa 13 if ($data == "") return ""; 14 $corrige = explode("-",$data); 15 $corrige = $corrige[2]."/".$corrige[1]."/".$corrige[0]; 16 return $corrige; 17 Das linhas 18 a 23 aparecerá o método formata_dollar 18 public function formata_dollar($valor) {//converte valor de U$ para R$ 19 $valor = str_replace('.','',$valor); 20 $valor = str_replace(',','.',$valor); 21 if(empty($valor)) return "0.00"; 22 return $valor; 23 Na linha 19 o símbolo (.) é substituído por nada, e na linha 20 o (,) é substituído por (.), abaixo há um if de uma linha só retornando se vazio o valor para 0.00. E o script da linha 24 é o contrário. Os scripts das linhas 25 a 32 são dois arrays um de mês e outro de semana para recuperar o nome e m português, pois em PHP na função date recuperamos o nome em inglês apenas. O script das linhas 33 a 35 recupera em uma string o número de caracteres definidos 5
no atributo $caracter e retornam a string mais três pontinhos. Os scripts das linhas 37 a 42 retornam a data atual e o horário atual através do uso da função date, j á previamente explicada no capitulo 4. E as demais linhas finais são para redirecionamento de URL e redirecionamento de URL com uma mensagem em javascript. Ambas usando javascript, pois a função nata do PHP header location é falha. Pois se eu tiver uma linha em HTML junto ao script ela já não funciona. Agora veja abaixo como criar um objeto e usar cada método acima. <?php include "class.php"; //inclui a classe $hoje = date( Y )."-".date( m )."-".date( d );//cria data em aaaa-mm-dd $ano = date( Y );//recupera ano atual $mes = date( m ); //recupera mês atual $dia = date( d ); //recupera dia atual $sem = date( w ); //recupera semana atual $basics = new basics; //cria objeto echo $basics->nome_mes($mes-1); //acessa o método nome mês da classe basics echo "<br />"; echo $basics->semana($sem); echo "<br />"; echo $basics->formata_data_br($hoje); echo "<br />"; echo $basics->formata_data_banco($basics->formata_data_br($hoje)); echo "<br />"; echo $basics->formatareal(1.200,00);?> Resultado: Fevereiro Quarta-Feira 01/02/2012 2012-02-01 1200.00 6.2 ASSOCIAÇÃO Associação é o mecanismo pelo qual um objeto utiliza os recursos de outro. Pode tratar-se de uma associação simples "usa um" ou de um acoplamento "parte de". Por exemplo: Preciso acessar um método que está em 6
outra classe ou em outro método. Por exemplo no exemplo abaixo, se eu fizer um método que será o combo box de meses, eu posso instanciar no código o método nome_mes, chamando através de $this->nome_mes($mes) ou self::nome_mes($mes) Veja o exemplo: public function nome_mes($mes) { $arr = array('janeiro','fevereiro','março','abril','maio','junho','julho','agosto','setembro ','Outubro','Novembro','Dezembro'); return $arr[$mes]; public function combo_mes($mes) { $combo = "<select name=\"mes\">"; for($i=1;$i<=12;$i++){ $combo.= "<option self::nome_mes($mes)."<option>" value=\"".$i."\">". ; $combo.= "</select>"; return $combo; 6.3. SUB-CLASSE Sub-classe é uma nova classe originada de sua classe pai. Ex: Classe mostra produto dentro da classe carrinho de compras. 6.4. HERANÇA Herança (ou generalização) é o mecanismo pelo qual uma classe (sub-classe) pode estender outra classe (superclasse), aproveitando seus comportamentos (métodos) e variáveis possíveis (atributos). Um exemplo de herança: Produto estende da classe pedido, não consigo comprar um produto sem passar pelo pedido. Igual ao exemplo anterior, posso criar uma sub-classe chamada combo que se estende de basics. Veja como ficará. <?php class combo extends basics{ public function combo_mes($mes) { $combo = "<select name=\"mes\">"; for($i=1;$i<=12;$i++){ $combo.= "<option basics::nome_mes($mes)."<option>" 7
$combo.= "</select>"; return $combo; value=\"".$i."\">". ; Veja que ao invés de usar self:: ou $this-> usa-se o nome da classe seguido de :: (duas vezes dois pontos). Uma classe pode extender (extends) outra classe qualquer Todos os atributos e métodos estão disponíveis imediatamente pela variável nome da classe seguido de :: O construtor da superclasse deve ser chamado explicitamente pe lo construtor da subclasse definição da subclasse deve incluir a definição da s uperclasse; 6.5 ENCAPSULAMENTO O encapsulamento é um dos recursos mais interessantes da programação orientada a objetos. Encapsular significa, na programação, esconder os dados contidos nas propriedades de uma classe. Qualquer classe é completamente responsável pelos dados que ela transporta e necessita que os mesmos se mantenham íntegros, ou seja, sem alterações não previstas durando o fluxo da aplicação. Por exemplo, não é necessário conhecer todo o funcionamento interno de um carro para poder dirigi-lo. Para isso é escondido por baixo da lataria tudo que faz com que o carro funcione, deixando apenas para o usuário o que é realmente necessário para se dirigir. Assim é garantido que o usuário leigo, ou que não saiba completamente do funcioname nto do carro não mexa na peça errada, corte o fio errado ou faça qualque r outra besteira. Na programação orientada a objetos é possível utilizar do encapsulamento dando permissões de acessos aos atributos das classes. Assim podemos dizer quem pode acessar seus atributos diretamente ou não. São eles: 6.5.1. Public A palavra chave public informa que a propriedade ou o método são públicos, ou seja, qualquer um pode acessar (desde subclasses como outras classes que estão a instanciando). 6.5.2. Private Já a palavra chave private informa que a propriedade ou método só 8
podem ser acessados internamente na classe. Nem seus filhos podem acessá-lo. 6.5.3. Protected Enquanto isso protected indica que subclasses podem acessar, mas outras classes ou funções não têm essa permissão. Veja abaixo exemplos: Com o PUBLIC a sub classe acessa o método da classe pai sem problema, agora veja os outros casos o que acontece. CÓDIGO FONTE PUBLIC <?php class basics { public $mes; public function nome_mes($mes) { //converte mês em número para o nome em pt $arr = array('janeiro','fevereiro','março','abril','maio','junho','julho','agosto', 'Setembro','Outubro','Novembro','Dezembro'); return $arr[$mes]; class combos extends basics{ public function combo_mes($mes) { $combo = "<select name=\"mes\">"; for($i=0;$i<12;$i++){ $combo.= "<option value=\"".($i+1)."\">".basics::nome_mes($i)."</option>"; $combo.= "</select>"; return $combo; $obj = new combos; echo $obj->combo_mes(date('m'));?> Ao mudar o método nome_mes para private ao processar o seguinte erro aparece. Fatal error : Call to private method basics::nome_mes() from context 'combos' in C:\xampp\htdocs\encapsulamento.php on line 17 9
Não é acessado, pois private só deixa acessar dentro da classe pai a classe filha não pode acessar. Agora faremos o mesmo caso com PROTECTED e a classe filha pode acessar normalmente, veja como fica o código com PROTECTED. class basics { public $mes; protected function nome_mes($mes) { //converte mês em número para o nome em pt $arr = array('janeiro','fevereiro','março','abril','maio','junho','julho','agosto', 'Setembro','Outubro','Novembro','Dezembro'); return $arr[$mes]; class combos extends basics{ public function combo_mes($mes) { $combo = "<select name=\"mes\">"; for($i=0;$i<12;$i++){ $combo.= "<option value=\"".($i+1)."\">".basics::nome_mes($i)."</option>"; $combo.= "</select>"; return $combo; $obj = new combos; echo $obj->combo_mes(date('m')); Veja que não causa erro, pois é acessado normalmente. Porém outra classe que não se estende não pode acessar. 6.6 Polimorfismo Polimorfismo é um termo grego que significa muitas formas ( poli: muitas, morphos: formas). Na programação é o mesmo que dizer que várias classes podem possuir a mesma estrutura e comportamentos diferentes. Ao utilizar he rança não apenas podemos reutilizar métodos da classe pai, como também podemos 10
sobrescrever os métodos da classe pai, fazendo assim com que algumas características sejam modificadas. Por exemplo na classe combo eu poderia utilizar o nome do mês abrevidado, veja como ficaria <?php class basics { public $mes; public function nome_mes($mes) { //converte mês em número para o nome em pt $arr = array('janeiro','fevereiro','março','abril','maio','junho','julho','agosto', 'Setembro','Outubro','Novembro','Dezembro'); return $arr[$mes]; class combos extends basics{ public function nome_mes($mes) { //converte mês em número para o nome em pt $arr = array('jan','fev','mar','abr','mai','jun','jul','ago','set','out','nov','dez '); return $arr[$mes]; public function combo_mes($mes) { $combo = "<select name=\"mes\">"; for($i=0;$i<12;$i++){ $combo.= "<option value=\"".($i+1)."\">".self::nome_mes($i)."</option>"; $combo.= "</select>"; return $combo; $obj = new combos; echo $obj->combo_mes(date('m'));?> Assim reaproveitamos a estrutura dos objetos mudando apenas o que for preciso. Mas às vezes é preciso que 11
mesmo sobrescrevendo um método, o código na classe pai seja executado. Para isso basta você chamar o nome do método, mudando onde tem self para parente ou o nome da classe pai. 12