Explicação detalhada da API de reflexão do PHP

A API de reflexão em PHP é como o pacote java.lang.reflect em Java. Consiste em uma série de classes internas que podem analisar propriedades, métodos e classes. É semelhante em alguns aspectos às funções de objeto, como get_class_vars(), mas é mais flexível e pode fornecer mais informações. A API de reflexão também funciona com os recursos orientados a objeto mais recentes do PHP, como controle de acesso, interfaces e classes abstratas. As antigas funções de classe não são tão fáceis de usar com esses novos recursos. Amigos que viram o código-fonte da estrutura devem ter um certo entendimento do mecanismo de reflexão do PHP, como injeção de dependência, pool de objetos, carregamento de classes, alguns padrões de design etc., todos usam o mecanismo de reflexão.

Classes parciais da API de reflexão

Usando essas classes na API de reflexão, é possível obter acesso a informações estendidas sobre objetos, funções e scripts em tempo de execução. Essas informações podem ser usadas para analisar classes ou construir estruturas.

tipo descrever
Reflexão Fornece a função estática export() para informações resumidas da classe
Classe de Reflexão Informações e ferramentas de classe
ReflectionMethod Informações e ferramentas do método de classe
Parâmetro de reflexão Informações do parâmetro do método
ReflectionProperty informações de atributo de classe
Função de Reflexão Informações e ferramentas de função
ReflexãoExtensão Informações da extensão PHP
ReflectionException classe de erro

Obter informações de classe

Usamos algumas funções em nosso trabalho para verificar atributos de classe, por exemplo: get_class_methods, getProduct, etc. Esses métodos têm grandes limitações para obter informações detalhadas sobre as classes.

Podemos obter informações sobre a classe por meio da classe API de reflexão: a exportação de método estático fornecida por Reflection e ReflectionClass. export pode fornecer quase todas as informações sobre a classe, incluindo o status de controle de acesso de atributos e métodos, os parâmetros exigidos por cada método, e cada A posição do método no documento de script. A saída do método estático de exportação dessas duas classes de ferramentas é a mesma, mas o uso é diferente.

Primeiro, construa uma classe simples

<?php 

classe Aluno { 
    public $nome; 
    $idade protegida; 
    $sexo privado; 

    public function __construct($nome, $idade, $sexo) 
    { 
        $this->setName($nome); 
        $this->setIdade($idade); 
        $this->setSexo($sexo); 
    } 

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

    Protected function setAge($age) 
    { 
        $this->age = $age; 
    } 

    função privada setSex($sex) 
    { 
        $this->sex = $sex; 
    } 
}

Use ReflectionClass::export() para obter informações de classe

ReflectionClass::export('Estudante');

Resultado da impressão:

 Saída ReflectionClass::export()

A classe ReflectionClass fornece muitas ferramentas e métodos. A lista fornecida no manual oficial é a seguinte:

 Classe de Reflexão

Use Reflection::export() para obter informações de classe 

$prodClass = new ReflectionClass('Estudante'); 
Reflexão::export($prodClass);

imprimir resultado

 Reflection::export() saída

Depois de criar o objeto ReflectionClass, você pode usar a classe de ferramentas Reflection para gerar as informações relevantes da classe Student. Reflection::export() pode formatar e exportar uma instância de qualquer classe que implemente a interface Reflector.

verificar classe

A classe de ferramenta ReflectionClass que aprendemos anteriormente sabe que essa classe fornece vários métodos de ferramenta para obter informações de classe. Por exemplo, podemos obter o tipo da classe Aluno, se ela pode ser instanciada

função da ferramenta

function classData(ReflectionClass $class) { 
    $details = ''; 
    $name = $class->getName(); // retorna o nome da classe para verificar 
    se ($class->isUserDefined()) { // verifica se a classe é definido por 
        $details definido pelo usuário .= "$name é definido pelo usuário" . PHP_EOL; 
    } 
    if ($class->isInternal()) { // Verifique se a classe é definida internamente por extensão ou núcleo 
        $details .= "$name é integrado" . PHP_EOL; 
    } 
    if ($class->isInterface()) { // Verifica se a classe é uma interface 
        $details .= "$name is interface" . PHP_EOL; 
    } 
    if ($class->isAbstract ()) { // Verifica se a classe é abstrata 
        $details .= "$name é uma classe abstrata" .PHP_EOL; 
    } 
    if ($class->isFinal()) { // Verifica se a classe é declarada final
        $details .= "$name é uma classe final" . PHP_EOL; 
    } 
    if ($class->isInstantiable()) { // . 
        = "$name pode ser instanciado" . PHP_EOL; 
    } else { 
        $details .= "$name não pode ser instanciado" . PHP_EOL; 
    } 
    return $detalhes; 
} 

$prodClass = new ReflectionClass('Student'); 
imprima dadosclasse($classeprod);

imprimir resultado

Aluno é definido pelo usuário 
Aluno pode ser instanciado

Além de obter as informações relevantes da classe, você também pode obter as informações relevantes do código-fonte, como o nome do arquivo da classe personalizada e as linhas inicial e final da classe no arquivo fornecido pelo objeto ReflectionClass.

function getClassSource(ReflectionClass $class) { 
    $path = $class->getFileName(); // Obtém o caminho absoluto do arquivo de classe 
    $lines = @file($path); // Obtém um array de todas as linhas do arquivo 
    $from = $class->getStartLine(); // Fornece a linha inicial da classe 
    $to = $class->getEndLine(); // Fornece a linha final da classe 
    $len = $to - $from + 1 ; 
    return implode(array_slice ($lines, $from - 1, $len)); 
} 

$prodClass = new ReflectionClass('Student'); 
var_dump(getClassSource($prodClass)); 

print result 
string 'class Student { 
    public $name ; 
    protegido $idade; 
    privado $sexo; 

    função pública __construct($nome, $idade, $sexo) 
    { 
        $this->setNome($nome);
        $this->setIdade($idade); 
        $this->setSexo($sexo); 
    } 

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

    Protected function setAge($age) 
    { 
        $this->age = $age; 
    } 

    função privada setSex($sex) 
    { 
        $this->sex = $sex; 
    } 
} 
' (comprimento = 486)

Vemos que getClassSource aceita um objeto ReflectionClass como seu parâmetro e retorna o código-fonte da classe correspondente. Esta função ignora o tratamento de erros, na prática os argumentos e códigos de resultado devem ser verificados!

Método de inspeção

Semelhante à inspeção de classes, os objetos ReflectionMethod podem ser usados ​​para inspecionar métodos em classes.

Existem duas maneiras de obter um objeto ReflectionMethod:

A primeira é obter um array de objetos ReflectionMethod através de ReflectionClass::getMethods(). A vantagem deste método é que ele não precisa saber o nome do método antecipadamente, e retornará os objetos ReflectionMethod de todos os métodos da classe .

A segunda é instanciar o objeto diretamente usando a classe ReflectionMethod. Desta forma, apenas um objeto de método de classe pode ser obtido e o nome do método precisa ser conhecido com antecedência.

Métodos utilitários para objetos ReflectionMethod:

 ReflectionMethod

ReflectionClass::getMethods()

Podemos obter um array de objetos ReflectionMethod através de ReflectionClass::getMethods().

$prodClass = new ReflectionClass('Estudante'); 
$metodos = $prodClass->getMethods(); 
var_dump($métodos);

imprimir resultado

array (size=4) 
  0 => & 
    object(ReflectionMethod)[2] 
      public 'name' => string '__construct' (comprimento=11) 
      public 'class' => string 'Student' (comprimento=7) 
  1 => & 
    object(ReflectionMethod)[3] 
      public 'name' => string 'setName' (comprimento=7) 
      public 'class' => string 'Student' (comprimento=7) 
  2 => & 
    object(ReflectionMethod)[4] 
      public 'name' => string 'setAge' (comprimento=6) 
      public 'class' => string 'Student' (comprimento=7) 
  3 => & 
    object(ReflectionMethod)[5] 
      public 'name' => string'setSex' (comprimento=6) 
      public 'classe' => string 'Estudante' (comprimento=7)

Pode-se ver que obtivemos a matriz de objetos ReflectionMethod do aluno, cada elemento é um objeto, que possui duas propriedades públicas, name é o nome do método e class é a classe à qual ele pertence. Podemos chamar métodos de objeto para obter informações de método.

ReflectionMethod

Use diretamente a classe ReflectionMethod para obter informações sobre métodos de classe

$method = new ReflectionMethod('Student', 'setName'); 
var_dump($método);

imprimir resultado

object(ReflectionMethod)[1] 
  public 'name' => string 'setName' (comprimento=7) 
  public 'class' => string 'Student' (comprimento=7)

Perceber

No PHP5, ReflectionMethod::retursReference() não retornará true se o método inspecionado retornar apenas objetos (mesmo se os objetos forem atribuídos ou passados ​​por referência). ReflectionMethod::returnsReference() retorna true somente se o método inspecionado tiver sido explicitamente declarado para retornar referências (com um símbolo & precedendo o nome do método).

Verifique os parâmetros do método

No PHP5, ao declarar um método de classe, você pode restringir o tipo de objeto no parâmetro, então torna-se necessário verificar os parâmetros do método.

Semelhante à inspeção de métodos, um objeto ReflectionParameter pode ser usado para inspecionar métodos em uma classe. Esse objeto pode informar o nome do parâmetro, se a variável pode ser passada por referência e também informa sobre dicas de tipo de parâmetro e se o método aceita valores nulos como parâmetros.

Existem também duas maneiras de obter objetos ReflectionParameter, que são muito semelhantes à obtenção de objetos ReflectionMethod:

A primeira é retornar um array de objetos ReflectionParameter através do método ReflectionMethod::getParameters(), que pode obter todos os objetos de parâmetro de um método.

A segunda é usar diretamente a classe ReflectionParameter para instanciar e obter objetos, este método só pode obter objetos com um único parâmetro.

Métodos utilitários para objetos ReflectionParameter:

 Parâmetro de reflexão

ReflectionMethod::getParameters()

Igual ao método get, este método retornará um array contendo objetos ReflectionParameter para cada parâmetro do método

$method = new ReflectionMethod('Student', 'setName'); 
$params = $método->getParameters(); 
var_dump($params);

imprimir resultado

array (size=1) 
  0 => & 
    object(ReflectionParameter)[2] 
      public 'name' => string 'name' (comprimento=4)

Parâmetro de reflexão

Vamos dar uma olhada neste método. Para um melhor entendimento, eu modifico o método setName da classe Aluno e adiciono dois parâmetros a, b

... 
    public function setName($name, $a, $b) 
    { 
        $this->name = $name; 
    } 
...

Primeiro, vamos ver o método de construção da classe ReflectionParameter

public ReflectionParameter::__construct ( string $ função , string $ parâmetro )

Você pode ver que a classe recebe dois parâmetros quando é instanciada:

$função: Quando você precisa obter uma função como função pública, você só precisa passar o nome da função. Quando a função é um método de classe, um array precisa ser passado no formato: array('class', 'function').

$parâmetro: Este parâmetro pode ser passado de duas formas, a primeira é o nome do parâmetro (sem o símbolo $), e a segunda é o índice do parâmetro. Observação: seja um nome de parâmetro ou um índice, o parâmetro deve existir, caso contrário, um erro será relatado.

Aqui está um exemplo:

$params = new ReflectionParameter(array('Student', 'setName'), 1); 
var_dump($params);

imprimir resultado

object(ReflectionParameter)[1] 
  public 'name' => string 'a' (comprimento=1)

Vamos definir outra função para testar

function foo($a, $b, $c) { } 
$reflect = new ReflectionParameter('foo', 'c'); 
var_dump($refletir);

imprimir resultado

object(ReflectionParameter)[2] 
  public 'name' => string 'c' (comprimento=1)

epílogo

A API de reflexão do PHP é muito poderosa, pode obter as informações detalhadas de uma classe. Podemos escrever uma classe por meio da API de reflexão para chamar dinamicamente o objeto Module, que pode carregar livremente plug-ins de terceiros e integrá-los aos sistemas existentes. Não há necessidade de codificar código de terceiros no código original. Embora o uso de reflexão no desenvolvimento real seja relativamente pequeno, entender a API de reflexão é muito útil para entender a estrutura do código e desenvolver modelos de negócios no trabalho. Este post do blog foi escrito de forma intermitente por um longo tempo (principalmente por preguiça!), se houver algum erro e deficiência, por favor, corrija-me e sugira! !

Acho que você gosta

Origin blog.csdn.net/Api_k/article/details/132120239
Recomendado
Clasificación