Características PHP

Resumo : neste tutorial, você aprenderá como usar características do PHP para compartilhar funcionalidades entre classes independentes, que não estão na mesma hierarquia de herança.

Introdução às características do PHP

A reutilização de código é um dos aspectos mais importantes da programação orientada a objetos. No PHP, você usa herança para permitir a reutilização de código em diferentes classes com a mesma hierarquia de herança.

Para conseguir a reutilização de código, você move a funcionalidade comum das classes para métodos da classe pai. No entanto, a herança torna o código fortemente acoplado. Portanto, o uso excessivo da herança pode dificultar a manutenção do código.

Para superar esse problema, o PHP 5.4 introduziu uma nova unidade de código reutilizável chamada trait. As características permitem reutilizar vários métodos livremente em muitas classes diferentes que não precisam estar na mesma hierarquia de classes.

A herança permite que as classes reutilizem o código verticalmente, enquanto as características permitem que as classes reutilizem o código horizontalmente.

Uma característica é semelhante a uma classe, mas serve apenas para agrupar métodos de maneira refinada e consistente. O PHP não permite que você crie uma instância de um Trait como uma instância de uma classe. E não existe tal conceito de instância de uma característica.

Exemplo de característica PHP

Para definir uma característica, você usa a palavra-chave trait seguida de um nome da seguinte maneira:

<?php

trait Logger
{
	public function log($msg)
	{
		echo '<pre>';
		echo date('Y-m-d h:i:s') . ':' . '(' . __CLASS__ . ') ' . $msg . '<br/>';
		echo '</pre>';
	}
}
Linguagem de código:  HTML, XML  ( xml )

Para usar uma característica em uma classe, você usa a usepalavra-chave. Todos os métodos da característica estão disponíveis na classe onde ela é utilizada. Chamar um método de uma característica é semelhante a chamar um método de instância.

O exemplo a seguir demonstra como usar o Loggertrait na BankAccountclasse:

class BankAccount
{
	use Logger;

	private $accountNumber;

	public function __construct($accountNumber)
	{
		$this->accountNumber = $accountNumber;
		$this->log("A new $accountNumber bank account created");
	}
}
Linguagem de código:  PHP  ( php )

E você pode reutilizar a Loggercaracterística na Userclasse da seguinte maneira:

class User
{
	use Logger;

	public function __construct()
	{
		$this->log('A new user created');
	}
}
Linguagem de código:  PHP  ( php )

Ambas BankAccountas Userclasses e reutilizam métodos da Loggercaracterística, o que é muito flexível.

Usando múltiplas características

Uma classe pode usar várias características. O exemplo a seguir demonstra como usar várias características na classe IDE. Ele simula o modelo de compilação C em PHP para fins de demonstração.

<?php

trait Preprocessor
{
	public function preprocess()
	{
		echo 'Preprocess...done' . '<br/>';
	}
}
trait Compiler
{
	public function compile()
	{
		echo 'Compile code... done' . '<br/>';
	}
}

trait Assembler
{
	public function createObjCode()
	{
		echo 'Create the object code files... done.' . '<br/>';
	}
}

trait Linker
{
	public function createExec()
	{
		echo 'Create the executable file...done' . '<br/>';
	}
}

class IDE
{
	use Preprocessor, Compiler, Assembler, Linker;

	public function run()
	{
		$this->preprocess();
		$this->compile();
		$this->createObjCode();
		$this->createExec();

		echo 'Execute the file...done' . '<br/>';
	}
}

$ide = new IDE();
$ide->run();
Linguagem de código:  HTML, XML  ( xml )

Compondo múltiplas características

PHP permite compor múltiplas características em uma característica usando a useinstrução na declaração da característica. Por exemplo:

<?php

trait Reader
{
	public function read($source)
	{
		echo sprintf('Read from %s <br>', $source);
	}
}

trait Writer
{
	public function write($destination)
	{
		echo sprintf('Write to %s <br>', $destination);
	}
}

trait Copier
{
	use Reader, Writer;

	public function copy($source, $destination)
	{
		$this->read($source);
		$this->write($destination);
	}
}

class FileUtil
{
	use Copier;

	public function copyFile($source, $destination)
	{
		$this->copy($source, $destination);
	}
}
Linguagem de código:  HTML, XML  ( xml )

Como funciona.

  • Primeiro, defina Readere Writertrate.
  • Em segundo lugar, defina uma nova característica chamada Copierque seja composta por características Reader e Writer. No copy()método da Copiercaracterística, chame os  métodos read()e write()das características Readere Writer.
  • Terceiro, use a Copiercaracterística no  copyFile()método da FileUtilclasse para simular a cópia do arquivo.

Resolução de conflitos de métodos do trait PHP

Substituindo o método de característica

Quando uma classe usa múltiplas características que compartilham o mesmo nome de método, o PHP irá gerar um erro fatal. 

Felizmente, você pode instruir o PHP a usar o método usando a inteadofpalavra-chave. Por exemplo:

<?php

trait FileLogger
{
	public function log($msg)
	{
		echo 'File Logger ' . date('Y-m-d h:i:s') . ':' . $msg . '<br/>';
	}
}

trait DatabaseLogger
{
	public function log($msg)
	{
		echo 'Database Logger ' . date('Y-m-d h:i:s') . ':' . $msg . '<br/>';
	}
}

class Logger
{
	use FileLogger, DatabaseLogger{
		FileLogger::log insteadof DatabaseLogger;
	}
}

$logger = new Logger();
$logger->log('this is a test message #1');
$logger->log('this is a test message #2');
Linguagem de código:  HTML, XML  ( xml )

Ambas FileLoggeras DatabaseLoggercaracterísticas e têm o mesmo  log()método.

Na Loggerclasse, resolvemos o conflito de nome do método especificando que o  log()método do FileLoggertrait será usado em vez do DatabaseLogger‘s.

E se você quiser usar os dois log()métodos das características FileLoggere DatabaseLogger? nesse caso, você pode usar um alias para o método da característica dentro da classe que usa a característica.

Método de traço de alias

Ao usar aliases para o mesmo nome de método de múltiplas características, você pode reutilizar todos os métodos nessas características.

Você usa a aspalavra-chave para alias de um método de uma característica a um nome diferente dentro da classe que usa a característica.

O exemplo a seguir ilustra como criar um alias para o método trait para resolver o conflito de nome do método:

class Logger
{
	use FileLogger, DatabaseLogger{
		DatabaseLogger::log as logToDatabase;
		FileLogger::log insteadof DatabaseLogger;
	}
}

$logger = new Logger();
$logger->log('this is a test message #1');
$logger->logToDatabase('this is a test message #2');Linguagem de código:  PHP  ( php )

O método  log()da DatabaseLoggerclasse possui um novo nome ( logToDatabase) no contexto da Logger classe.

Neste tutorial, você aprendeu como usar características do PHP para reutilizar o código fora de uma hierarquia de classes.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *