Metaprogramação, Exceções e Métodos Mágicos em PHP
Classificado em Computação
Escrito em em
português com um tamanho de 74,76 KB
Índice de Funções de Array
- array_change_key_case — Modifica todas as chaves em um array
- array_chunk — Divide um array em pedaços
- array_combine — Cria um array usando um array para chaves e outro para valores
- array_count_values — Conta as frequências de cada valor de um array
- array_diff_assoc — Computa a diferença entre arrays com checagem adicional de índice
- array_diff_key — Registra a diferença entre arrays usando chaves para comparação
- array_diff_uassoc — Computa a diferença entre arrays com checagem adicional de índice que é feita por uma função de callback fornecida pelo usuário
- array_diff_ukey — Computa a diferença de arrays usando uma função callback na comparação de chaves
- array_diff — Analisa as diferenças entre arrays
- array_fill_keys — Preenche um array com valores, especificando chaves
- array_fill — Preenche um array com valores
- array_filter — Filtra os elementos da array usando uma função de callback
- array_flip — Inverte as relações entre chaves e valores
- array_intersect_assoc — Computa a interseção de arrays com uma verificação adicional de índice
- array_intersect_key — Computa a interseção de array comparando pelas chaves
- array_intersect_uassoc — Computa a interseção de arrays com checagem de índice adicional, compara índices por uma função de callback
- array_intersect_ukey — Computa a interseção de arrays usando uma função de callback nas chaves para comparação
- array_intersect — Calcula a interseção entre arrays
- array_key_exists — Checa se uma chave ou índice existe em um array
- array_keys — Retorna todas as chaves de um array
- array_map — Aplica uma função em todos os elementos dos arrays dados
- array_merge_recursive — Funde dois ou mais arrays recursivamente
- array_merge — Funde um ou mais arrays
- array_multisort — Ordena múltiplos arrays ou arrays multidimensionais
- array_pad — Expande um array para um certo comprimento utilizando um determinado valor
- array_pop — Retira um elemento do final do array
- array_product — Calcula o produto dos valores de um array
- array_push — Adiciona um ou mais elementos no final de um array
- array_rand — Retorna um ou mais elementos aleatórios de um array
- array_reduce — Reduz um array para um único valor através de um processo iterativo utilizando uma função
- array_replace_recursive — Substitui elementos de arrays passados no primeiro array recursivamente
- array_replace — Substitui elementos de arrays passados no primeiro array
- array_reverse — Retorna um array com os elementos na ordem inversa
- array_search — Procura por um valor em um array e retorna sua chave correspondente caso seja encontrado
- array_shift — Retira o primeiro elemento de um array
- array_slice — Extrai uma parcela de um array
- array_splice — Remove uma parcela do array e substitui com outros elementos
- array_sum — Calcula a soma dos elementos de um array
- array_udiff-assoc — Computa a diferença entre arrays com checagem adicional de índice, compara dados por uma função de callback
- array_udiff_uassoc — Computa a diferença entre arrays com checagem adicional de índice, compara dados e índices por uma função de callback
- array_udiff — Computa a diferença de arrays usando uma função de callback para comparação dos dados
- array_uintersect_assoc — Computa a interseção de arrays com checagem adicional de índice, compara os dados utilizando uma função de callback
- array_uintersect_uassoc — Computa a interseção de arrays com checagem adicional de índice, compara os dados e os índices utilizando funções de callback
- array_uintersect — Computa a interseção de array, comparando dados com uma função callback
- array_unique — Remove os valores duplicados de um array
- array_unshift — Adiciona um ou mais elementos no início de um array
- array_values — Retorna todos os valores de um array
- array_walk_recursive — Aplica uma função do usuário recursivamente para cada membro de um array
- array_walk — Aplica uma determinada função em cada elemento de um array
- array — Cria um array
- arsort — Ordena um array em ordem decrescente mantendo a associação entre índices e valores
- asort — Ordena um array mantendo a associação entre índices e valores
- compact — Cria um array contendo variáveis e seus valores
- count — Conta o número de elementos de uma variável, ou propriedades de um objeto
- current — Retorna o elemento corrente em um array
- each — Retorna o par chave/valor corrente de um array e avança o seu cursor
- end — Faz o ponteiro interno de um array apontar para o seu último elemento
- extract — Importa variáveis para a tabela de símbolos a partir de um array
- in_array — Checa se um valor existe em um array
- key — Retorna uma chave de um array
- krsort — Ordena um array pelas chaves em ordem decrescente
- ksort — Ordena um array pelas chaves
- list — Cria variáveis como se fossem arrays
- natcasesort — Ordena um array utilizando o algoritmo da "ordem natural" sem diferenciar maiúsculas e minúsculas
- natsort — Ordena um array utilizando o algoritmo da "ordem natural"
- next — Avança o ponteiro interno de um array
- pos — Sinônimo de current
- prev — Retrocede o ponteiro interno de um array
- range — Cria um array contendo uma faixa de elementos
- reset — Faz o ponteiro interno de um array apontar para o seu primeiro elemento
- rsort — Ordena um array em ordem decrescente
- shuffle — Mistura os elementos de um array
- sizeof — Sinônimo de count
- sort — Ordena um array
- uasort — Ordena um array utilizando uma função de comparação definida pelo usuário e mantendo as associações entre chaves e valores
- uksort — Ordena um array pelas chaves utilizando uma função de comparação definida pelo usuário.
- usort — Ordena um array pelos valores utilizando uma função de comparação definida pelo usuário
Índice de Funções de String
- addcslashes — String entre aspas com barras no estilo C
- addslashes — Adiciona barras invertidas a uma string
- bin2hex — Converte um dado binário em representação hexadecimal
- chop — Sinônimo de rtrim
- chr — Retorna um caractere específico
- chunk_split — Divide uma string em pequenos pedaços
- convert_cyr_string — Converte de um conjunto de caracteres cirílico para outro
- convert_uudecode — Decodifica uma string codificada com uuencode
- convert_uuencode — Codifica com uuencode uma string
- count_chars — Retorna informações sobre os caracteres usados numa string
- crc32 — Calcula polinômio crc32 de uma string
- crypt — Encriptação unidirecional de string (hashing)
- echo — Exibe uma ou mais strings
- explode — Divide uma string em strings
- fprintf — Escreve uma string formatada para um stream
- get_html_translation_table — Retorna a tabela de tradução usada por htmlspecialchars e htmlentities
- hebrev — Converte texto lógico Hebraico para texto visual
- hebrevc — Converte um texto lógico Hebraico para um texto visual com conversão newline
- hex2bin — Decodifica uma string binária codificada hexadecimalmente
- html_entity_decode — Converte todas as entidades HTML para os seus caracteres
- htmlentities — Converte todos os caracteres aplicáveis em entidades HTML.
- htmlspecialchars_decode — Converte entidades HTML especiais para caracteres
- htmlspecialchars — Converte caracteres especiais para a realidade HTML
- implode — Junta elementos de uma matriz em uma string
- join — Sinônimo de implode
- lcfirst — Torna minúsculo o primeiro caractere de uma string
- levenshtein — Calcula a distância Levenshtein entre duas strings
- localeconv — Obtém a informação da formatação numérica
- ltrim — Retira espaços em branco (ou outros caracteres) do início da string
- md5_file — Calcula hash md5 de um dado arquivo
- md5 — Calcula o "hash MD5" de uma string
- metaphone — Calcula a metaphone key de uma string
- money_format — Formata um número como uma string de moeda
- nl_langinfo — Retorna informação de linguagem e local
- nl2br — Insere quebras de linha HTML antes de todas newlines em uma string
- number_format — Formata um número com os milhares agrupados
- ord — Retorna o valor ASCII do caractere
- parse_str — Converte a string em variáveis
- print — Mostra uma string
- printf — Mostra uma string formatada
- quoted_printable_decode — Converte uma string quoted-printable para uma string de 8 bit
- quoted_printable_encode — Converte uma string de 8 bits em uma string quoted-printable
- quotemeta — Adiciona uma barra invertida antes dos meta caracteres
- rtrim — Retira espaço em branco (ou outros caracteres) do final da string
- setlocale — Define informações locais
- sha1_file — Calcula a hash sha1 de um arquivo
- sha1 — Calcula a hash sha1 de uma string
- similar_text — Calcula a similaridade entre duas strings
- soundex — Calcula a chave soundex de uma string
- sprintf — Retorna a string formatada
- sscanf — Interpreta a entrada de uma string de acordo com um formato
- str_getcsv — Analisa uma string CSV e retorna os dados em um array
- str_ireplace — Versão que não diferencia maiúsculas e minúsculas de str_replace.
- str_pad — Preenche uma string para um certo tamanho com outra string
- str_repeat — Repete uma string
- str_replace — Substitui todas as ocorrências da string de procura com a string de substituição
- str_rot13 — Executa a transformação rot13 em uma string
- str_shuffle — Mistura uma string aleatoriamente
- str_split — Converte uma string para um array
- str_word_count — Retorna informação sobre as palavras usadas em uma string
- strcasecmp — Comparação de strings sem diferenciar maiúsculas e minúsculas segura para binário
- strchr — Sinônimo de strstr
- strcmp — Comparação de string segura para binário
- strcoll — Comparação de string baseada no local
- strcspn — Encontra o tamanho do segmento inicial que não contenha a máscara
- strip_tags — Retira as tags HTML e PHP de uma string
- stripcslashes — Desfaz o efeito de addcslashes
- stripos — Encontra a primeira ocorrência de uma string sem diferenciar maiúsculas e minúsculas
- stripslashes — Desfaz o efeito de addslashes
- stristr — strstr sem diferenciar maiúsculas e minúsculas
- strlen — Retorna o tamanho de uma string
- strnatcasecmp — Comparação de strings sem diferenciar maiúsculas/minúsculas usando o algoritmo "natural order"
- strnatcmp — Comparação de strings usando o algoritmo "natural order"
- strncasecmp — Comparação de string caso-sensitivo de Binário seguro dos primeiros n caracteres
- strncmp — Comparação de string segura para binário para os primeiros n caracteres
- strpbrk — Procura na string por um dos caracteres de um conjunto
- strpos — Encontra a posição da primeira ocorrência de uma string
- strrchr — Encontra a última ocorrência de um caractere em uma string
- strrev — Reverte uma string
- strripos — Encontra a posição da última ocorrência de uma string case-insensitive em uma string
- strrpos — Encontra a posição da última ocorrência de um caractere em uma string
- strspn — Encontra o comprimento do segmento inicial combinando com a máscara
- strstr — Encontra a primeira ocorrência de uma string
- strtok — Tokeniza uma string
- strtolower — Converte uma string para minúsculas
- strtoupper — Converte uma string para maiúsculas
- strtr — Traduz certos caracteres
- substr_compare — A comparação binária entre duas strings de um offset até o limite do comprimento de caracteres
- substr_count — Conta o número de ocorrências de uma substring
- substr_replace — Substitui o texto dentro de uma parte de uma string
- substr — Retorna uma parte de uma string
- trim — Retira espaço no início e final de uma string
- ucfirst — Converte para maiúscula o primeiro caractere de uma string
- ucwords — Converte para maiúsculas o primeiro caractere de cada palavra
- vfprintf — Escreve uma string formatada para um stream
- vprintf — Mostra uma string formatada
- vsprintf — Retorna uma string formatada
- wordwrap — Quebra uma string em um dado número de caracteres
Como usar Metaprogramação em PHP?
Mas a linguagem também permite que um script consiga alterar seu próprio comportamento em tempo de execução. Isso pode ser útil para otimizar trechos de código. Este recurso é possível com o comando "eval". Abaixo é mostrado um exemplo de código que não usa e outro que usa a metaprogramação.
Na função abaixo, são feitas duas comparações a cada iteração do loop:
/**
* Função de exemplo
* @param array[int] $vetor Vetor de números
* @param bool $somar Indica se o elemento do vetor deve ser somado com 1
* @param bool $multiplicar Indica se o elemento do vetor deve ser multiplicado por 2
* @return void
*/
function exemplo($vetor, $somar, $multiplicar){
foreach($vetor as $elemento){
if($somar){
$elemento += 1;
}
if($multiplicar){
$elemento *= 2;
}
echo $elemento;
}
}Usando metaprogramação, primeiro seria montar o código que desejamos executar, depois passaríamos para que ele seja avaliado com "eval":
/**
* Função de exemplo
* @param array[int] $vetor Vetor de números
* @param bool $somar Indica se o elemento do vetor deve ser somado com 1
* @param bool $multiplicar Indica se o elemento do vetor deve ser multiplicado por 2
* @return void
*/
function exemplo($vetor, $somar, $multiplicar){
$codigo = 'foreach ($vetor as $elemento) {';
if($somar){
$codigo .= '$elemento += 1;';
}
if($multiplicar){
$codigo .= '$elemento *= 2;';
}
$codigo .= 'echo $elemento;';
$codigo .= '}';
// Executar o código gerado dinamicamente
eval($codigo);
}
O segundo código tende a ser mais rápido, pois na variável
$codigo serão colocadas apenas as instruções desejáveis de serem realizadas durante o loop. Se forem passados os valores true e true para $somar e $multiplicar, então o código gerado na variável $codigo seria:foreach($vetor as $elemento){
$elemento += 1;
$elemento *= 2;
echo $elemento;
}Note que o loop não apresenta condições internamente, o que tornaria a iteração mais rápida.
Entretanto, trabalhar com metaprogramação não é recomendado para otimizar tudo. Pode ser utilizado em códigos de caixa preta, onde a implementação não costuma ser consultada, ou em trechos onde a performance precisa ser muito alta. Escrever um código e jogá-lo em uma variável é uma tarefa arriscada, já que o interpretador só conseguirá detectar erros de sintaxe no código gerado no momento em que o mesmo é avaliado (com o comando "eval"). Observe que isso inclui os delimitadores de instruções (ponto e vírgula), e tudo mais.
A metaprogramação torna o código menos legível e, por isso, também deve ser muito bem pensada antes de ser usada. Porém, abre brechas para a construção de estruturas bastante interessantes. Observe o código abaixo:
$busca = 'if ($i == $elemento) { $achou = true; $busca = ""; }';
$elemento = 7;
for($i = 0; $i < 10; $i++){
eval($busca);
echo $i;
}
Este código imprime números de 0 a 9, só que o código também quer aproveitar as iterações do loop para checar se um determinado elemento foi impresso ou não. Assim que o elemento é encontrado, não é mais necessário checar nas próximas iterações. Logo, o código que guarda a busca passa a ser uma string vazia. Quando uma string vazia é passada para "eval", nada é feito.
No exemplo, uma variável guardou um código capaz de mudar o seu próprio valor quando avaliado. Ela poderia mudar o código para outra coisa diferente de uma string vazia. Percebe o quanto a metaprogramação é complexa?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | namespace CHH;
trait MetaObject
{
protected static $__metaClass;
static function setMetaClass(MetaClass $metaClass)
{
static::$__metaClass = $metaClass;
}
static function getMetaClass()
{
if (null === static::$__metaClass) {
static::$__metaClass = new MetaClass;
}
return static::$__metaClass;
}
function __call($method, array $argv = array())
{
$metaClass = static::getMetaClass();
if (!$metaClass->respondsTo($method)) {
throw new \BadMethodCallException(sprintf(
'Call to undefined method %s', $method
));
}
return $metaClass->send($method, $argv, $this);
}
function __get($property)
{
$metaClass = static::getMetaClass();
if (property_exists($metaClass, $property)) {
return $this->$property = $metaClass->$property;
}
}
function __isset($property)
{
return property_exists(static::getMetaClass(), $property);
}
}
class MetaClass
{
protected $methods = array();
function extend($methods)
{
if ($methods instanceof MetaClass) {
$methods = $methods->getMethods();
}
foreach ($methods as $method => $body) {
$this->method($method, $body);
}
return $this;
}
function getMethods()
{
return $this->methods;
}
function method($name, \Closure $body)
{
$this->methods[$name] = $body;
return $this;
}
function property($name, $default = null)
{
$this->{$name} = $default;
return $this;
}
function respondsTo($method)
{
return isset($this->methods[$method]);
}
function send($method, array $argv = array(), $context = null)
{
if (!$this->respondsTo($method)) {
throw new \BadMethodCallException("Call to undefined Method $method");
}
$body = $this->methods[$method];
if (null !== $context) {
$body = $body->bindTo($context, get_class($context));
}
return call_user_func_array($body, $argv);
}
} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | namespace CHH\Test;
require_once __DIR__ . "/MetaObject.php";
use CHH\MetaObject;
class Animal
{
use MetaObject;
}
class Dog extends Animal
{
public $name;
protected $favouriteToy = "Stick";
function __construct($name = null)
{
$this->name = $name;
}
}
class MetaClassTest extends \PHPUnit_Framework_TestCase
{
/**
* Registers an Instance Meta Property at runtime and initializes it
* with a default value.
*/
function testRegisterMetaProperty()
{
$beethoven = new Dog;
Dog::getMetaClass()->property('no');
$this->assertTrue(isset($beethoven->no));
}
function testRegisterMetaMethod()
{
$beethoven = new Dog("Beethoven");
Dog::getMetaClass()->method('speak', function() {
return "Hello I'm {$this->name}";
});
$this->assertTrue(is_callable(array($beethoven, 'speak')));
$this->assertEquals("Hello I'm Beethoven", $beethoven->speak());
}
function testExtendWithArray()
{
$beethoven = new Dog("Beethoven");
Dog::getMetaClass()->extend([
"bark" => function() {
return "Woof! Woof!";
},
"isNamed" => function($name) {
return $this->name === $name;
}
]);
$this->assertFalse($beethoven->isNamed('Johnny'));
$this->assertEquals('Woof! Woof!', $beethoven->bark());
}
function testProtectedMemberAccess()
{
$beethoven = new Dog("Beethoven");
Dog::getMetaClass()->method("getFavouriteToy", function() {
return $this->favouriteToy;
});
$this->assertEquals("Stick", $beethoven->getFavouriteToy());
}
// I've to figure out this later. It's a quirk by PHP's
// behaviour with static inheritance.
function testInheritanceAndMetaClass()
{
$beethoven = new Dog("Beethoven");
Animal::getMetaClass()->method("foo", function() {
return "bar";
});
Dog::getMetaClass()->method("bar", function() {
return "bar";
});
$this->assertFalse(Animal::getMetaClass()->respondsTo("bar"));
$this->assertFalse(is_callable(array($beethoven, 'foo')));
$this->assertFalse(Animal::getMetaClass() === Dog::getMetaClass());
}
} |
Deixe-me começar com um problema da vida real que foi frequentemente apontado como uma falha no PHP 4. Como você deve se lembrar, no PHP 4 você definia um construtor de uma classe assim:
|
Em outras palavras, a construção era uma função com o mesmo nome da classe. O PHP 5 introduziu uma nova semântica de construtor:
|
Isso foi feito para resolver um problema que a maioria dos desenvolvedores PHP sempre teve – ou seja, como chamar o construtor de um pai, se você não sabe o nome dele. No PHP 5 é fácil:
|
Fácil! Como fazemos isso no PHP 4? Bem, nós codificamos o nome ou usamos um pouco de metaprogramação:
|
Qual seria o problema em simplesmente codificar parent::Bar() aqui? Pense no que acontecerá quando você criar uma subclasse de Foo. A classe SubFoo tentará chamar a função Bar() que não existe em Foo. A maneira como contornamos esse problema é a utilização de funções variáveis. Deixe-me tentar deixar isso mais claro usando um exemplo muito mais simples:
|
Em outras palavras, se você colocar um conjunto de parênteses após uma variável, o PHP tentará avaliar essa variável e usá-la como um nome de função. Funciona de maneira semelhante ao método PHP call_user_func, que permite que você passe uma representação de string de um nome de função e a chame. E como você pode gerar essa string dinamicamente, isso permite algumas técnicas de programação interessantes. Por exemplo, você pode criar uma função útil como esta:
Esta função recebe duas strings. Uma é o nome de uma classe e a outra é o nome de um método. Em seguida, ela inicializa a classe, se existir, e então chama um método de instância dessa classe especificado pelo nome. Você pode passar qualquer classe e qualquer nome de método e, se estiverem corretos, o método será executado. Há também algo chamado variáveis variáveis que podem ser úteis. Por exemplo, considere o seguinte:
O conteúdo de Não vou negar – PHP não é a linguagem mais bonita, e a falta de namespaces em sua biblioteca de funções resulta em alguns padrões de nomenclatura coloridos. Mas não seria tão prevalente e tão popular se não tivesse muito poder sob o capô. [tags]php, meta programming, programming[/tags] Tratamento de Erros e Exceções em PHP
1. Disparando ExceçõesQuando queremos disparar exceções utilizamos a palavra chave throw e em seguida passamos o objeto a ser disparado.Abaixo estamos criando uma classe que lê arquivos para distribuir para que outros desenvolvedores possam usá-la, e queremos que caso esse arquivo não exista, uma exceção seja disparada:
2. Capturando ExceçõesAgora somos o desenvolvedor que está utilizando esta classe. E percebi que quando informo um arquivo que não existe o sistema está mostrando um erro estranho: Isso ocorre por causa da exceção que a classe dispara quando não encontra um arquivo. Porém eu não posso deixar isso ser mostrado para o usuário do meu sistema, mas eu quero que ele guarde um log dessa mensagem de erro. Para isso utilizamos o bloco try onde ficará todo o código que tem a possibilidade de disparar uma exceção, e abaixo do try criaremos um catch, que será responsável por capturar qualquer exceção disparada no bloco try.No exemplo o bloco catch está recebendo uma variável $e do tipo Exception. Ela é exatamente o objeto da exceção disparada. Qualquer objeto derivado da classe Exception possui métodos que informam ao desenvolvedor um relato do que aconteceu. Esses métodos são:
Intercepções e Métodos Mágicos (Magic Methods)O PHP inseriu a partir da sua versão 5 o conceito de Intercepções. As intercepções são realizadas através de métodos conhecidos como Métodos Mágicos (Magic Methods).Os Métodos MágicosSão métodos opcionais que podemos colocar em nossas classes para executarem em momentos específicos e realizar ações especiais. Os principais são: 1. Método set()O método set é chamado toda vez que tentamos dar um valor a alguma propriedade da classe, independente dela ter sido declarada ou não.No exemplo queremos que qualquer propriedade que o usuário tentar adicionar seja armazenada em um array:
O método set recebe dois parâmetros. Um é o nome da propriedade que estamos tentando inserir e o outro é o valor que estamos atribuindo.2. Método get()Continuando com o exemplo passado, agora queremos recuperar esses valores armazenados. Atualmente não é possível, pois o array $_dados é privado e não é possível acessar de fora da classe.Para isso usamos o método __get, que intercepta toda vez que tentamos resgatar uma propriedade:
3. Método call()O método call é chamado toda vez que um método é chamado em uma classe e o PHP não o encontra. Com isso é possível definir comportamento padrão caso um método seja chamado.
O método call recebe dois parâmetros. Um é uma string com o nome do método que tentarão chamar e o outro é um array com os argumentos declarados. Se o método call não for encontrado, o PHP continua com seu fluxo normal e dispara um Fatal Error.Enviado por xKuRt em 03/02/2009 às 08:52 Itens relacionados Tutorial de POO no PHP: Herança e polimorfismo Tutorial de POO no PHP: Classes e Objetos Tutorial de POO no PHP: Padrões de projetos Tutorial de POO no PHP: Tratamento de erros Tutorial de POO no PHP: Encapsulamento Tutorial de POO no PHP: Membros da classe Tutorial de POO no PHP: Abstração Tutorial de POO no PHP: Programação Estruturada x Programação Orientada a Objetos Avaliação Avaliação desta publicação: 10.00; Total de avaliações: 1 Tutorial de POO no PHP: Abstração
Quando vamos desenvolver um programa, o certo não é pensar no projeto como um todo. A melhor forma de desenvolver é pensando e desenvolvendo em partes. Além de manter a sanidade do desenvolvedor, a estrutura do código fica bem organizada. Para criar uma estrutura bem feita é necessário abstrair seu desenvolvimento. Abstrair significa separar mentalmente, considerar isoladamente, simplificar. Assim nosso sistema deve ser separado de forma lógica com o objetivo de simplificar. 1. Classes AbstratasSendo assim, existem classes que chamamos de classes estruturais. Elas são responsáveis por manter uma estrutura padrão para seus filhos, independente do seu número. Ou seja, essas classes nunca serão instanciadas, pois somente seus filhos serão usados. Com isso, no nosso exemplo anterior, deveríamos ter criado uma classe chamada Cheque, que seria a estrutura padrão para as classes ChequeComum e ChequeEspecial, onde essas duas últimas herdariam Cheque e adicionariam ou sobrescreveriam apenas o que fosse relevante, e a classe Cheque seria abstrata.Para dizermos que uma classe é abstrata basta informarmos a palavra chave abstract.
Tentando instanciar a classe Cheque.
Isto vai causar um Fatal Error, pois ela é abstrata e não pode ser instanciada.
/
$cheque = new Cheque();
?>2. Classes FinaisHá também casos em que não queremos que uma classe seja estendida por mais nenhuma outra. Para fazermos isso definimos a classe como final utilizando a palavra chave com o mesmo nome, final. Vamos supor que a classe ChequeEspecial não pode ser estendida, porém alguém tentou de qualquer forma fazer isso:
Ao ver que estamos tentando herdar uma classe final,
o PHP lança um Fatal Error e para a execução do código
3. Métodos AbstratosAssim como classes, os métodos abstratos também são criados apenas para estruturação das classes filhas. Às vezes queremos que as classes derivadas de uma classe pai tenham obrigatoriamente um método específico, para garantir que não haja conflito em outros métodos que dependem desse primeiro.
Esta classe não precisa de cálculo de juros.
Mas se este método não for definido o PHP dispara um fatal error,
pois na classe pai esse método está como abstrato.
*/
public function calculaJuros()
{
return $this->valor; // não há juros;
}
}
?>Note que na classe Cheque o método calculaJuros() não é escrito, ele possui apenas sua assinatura. Isso é perfeitamente possível no caso de métodos abstratos.4. Métodos FinaisQuando um método é dito como final ele não pode ser sobrescrito, ou seja, a classe filha continua tendo acesso a ele, mas não pode mudá-lo.
Isto retorna um fatal error
*/
public function calculaTotal()
{
return 0.0;
}
}
?>Enviado por xKuRt em 03/02/2009 às 08:45 Itens relacionados Tutorial de POO no PHP: Intercepções Tutorial de POO no PHP: Encapsulamento Tutorial de POO no PHP: Herança e polimorfismo Tutorial de POO no PHP: Padrões de projetos Tutorial de POO no PHP: Tratamento de erros Tutorial de POO no PHP: Programação Estruturada x Programação Orientada a Objetos Tutorial de POO no PHP: Membros da classe Tutorial de POO no PHP: Classes e Objetos Avaliação Avaliação desta publicação: 10.00; Total de avaliações: 1 Tutorial de POO no PHP: Abstração (Cópia)
Quando vamos desenvolver um programa, o certo não é pensar no projeto como um todo. A melhor forma de desenvolver é pensando e desenvolvendo em partes. Além de manter a sanidade do desenvolvedor, a estrutura do código fica bem organizada. Para criar uma estrutura bem feita é necessário abstrair seu desenvolvimento. Abstrair significa separar mentalmente, considerar isoladamente, simplificar. Assim nosso sistema deve ser separado de forma lógica com o objetivo de simplificar. 1. Classes AbstratasSendo assim, existem classes que chamamos de classes estruturais. Elas são responsáveis por manter uma estrutura padrão para seus filhos, independente do seu número. Ou seja, essas classes nunca serão instanciadas, pois somente seus filhos serão usados. Com isso, no nosso exemplo anterior, deveríamos ter criado uma classe chamada Cheque, que seria a estrutura padrão para as classes ChequeComum e ChequeEspecial, onde essas duas últimas herdariam Cheque e adicionariam ou sobrescreveriam apenas o que fosse relevante, e a classe Cheque seria abstrata.Para dizermos que uma classe é abstrata basta informarmos a palavra chave abstract.
Tentando instanciar a classe Cheque.
Isto vai causar um Fatal Error, pois ela é abstrata e não pode ser instanciada.
/
$cheque = new Cheque();
?>2. Classes FinaisHá também casos em que não queremos que uma classe seja estendida por mais nenhuma outra. Para fazermos isso definimos a classe como final utilizando a palavra chave com o mesmo nome, final. Vamos supor que a classe ChequeEspecial não pode ser estendida, porém alguém tentou de qualquer forma fazer isso:
Ao ver que estamos tentando herdar uma classe final,
o PHP lança um Fatal Error e para a execução do código
3. Métodos AbstratosAssim como classes, os métodos abstratos também são criados apenas para estruturação das classes filhas. Às vezes queremos que as classes derivadas de uma classe pai tenham obrigatoriamente um método específico, para garantir que não haja conflito em outros métodos que dependem desse primeiro.
Esta classe não precisa de cálculo de juros.
Mas se este método não for definido o PHP dispara um fatal error,
pois na classe pai esse método está como abstrato.
*/
public function calculaJuros()
{
return $this->valor; // não há juros;
}
}
?>4. Métodos FinaisQuando um método é dito como final ele não pode ser sobrescrito, ou seja, a classe filha continua tendo acesso a ele, mas não pode mudá-lo.
Isto retorna um fatal error
*/
public function calculaTotal()
{
return 0.0;
}
}
?>Enviado por xKuRt em 03/02/2009 às 08:45 Itens relacionados Tutorial de POO no PHP: Classes e Objetos Tutorial de POO no PHP: Tratamento de erros Tutorial de POO no PHP: Membros da classe Tutorial de POO no PHP: Intercepções Tutorial de POO no PHP: Encapsulamento Tutorial de POO no PHP: Herança e polimorfismo Tutorial de POO no PHP: Programação Estruturada x Programação Orientada a Objetos Tutorial de POO no PHP: Padrões de projetos Avaliação Avaliação desta publicação: 10.00; Total de avaliações: 1 Tutorial de POO no PHP: Programação Estruturada x Programação Orientada a Objetos
Nos anos 60 uma linguagem de programação chamada SIMULA, criada por Kristen N. e Ole-Johan, utilizava uma nova forma de reaproveitamento de código. No lugar de quebrar o código em várias funções e criar pequenos procedimentos, foi adotado o que se chama de classes e subclasses. Já na década de 70 o Smalltalk foi criado por cientistas da Xerox. Ela foi a primeira linguagem que apresentava de forma completa os conceitos da programação orientada a objetos. O conceito era completamente novo e que levou certo tempo para as pessoas se acostumarem, e até hoje ainda causa arrepios em alguns desenvolvedores. 1. Programação EstruturadaA programação estruturada foi e ainda é bastante utilizada no mundo do desenvolvimento. Ela é baseada no conceito da modularização: o programa é quebrado em pequenos procedimentos, também conhecidos como funções. Assim é possível manter um aproveitamento razoável de código e criar funções genéricas que podem ser reaproveitadas entre projetos diferentes como, por exemplo, uma função que gera planilhas eletrônicas. Embora isso seja possível, criar algo muito genérico é bastante difícil. O número de parâmetros que essa função pode receber e o número de procedimentos executados repetidamente é muito grande e isso dificulta a manutenção do código. Com todos esses problemas o desenvolvimento é demorado, ou então, ele é rápido mas sua manutenção é bastante difícil, levando várias horas ou até mesmo dias para realizar uma pequena mudança. Como o reaproveitamento é pequeno, uma simples mudança precisa ser replicada em várias outras partes do código. 2. Programação Orientada a Objetos (POO)A programação orientada a objetos traz o mundo real para dentro do desenvolvimento. Se utilizada corretamente, seu programa pode simular a compra de um produto da forma como ela realmente é: Um produto é posto dentro de um carrinho de compras. Então esse carrinho segue até um caixa onde é calculado o valor da compra, dos juros, retirado os descontos e por último efetuando a compra. Simular o mundo real dentro do computador não é uma tarefa difícil utilizando essa “nova” técnica. Se considerarmos que tudo ao nosso redor é um objeto (um produto, um carro, uma pessoa, um banco, uma conta corrente) é possível fazer com que esses objetos interajam entre si. Então no lugar de nosso código ser:
Ele passa a ser:
|

