ReflectionProperty::getType

(PHP 7 >= 7.4.0, PHP 8)

ReflectionProperty::getTypeプロパティの型を取得する

説明

public ReflectionProperty::getType(): ?ReflectionType

プロパティに関連付けられた型を取得する

パラメータ

この関数にはパラメータはありません。

戻り値

プロパティが型を持っていれば、ReflectionType を返します。そうでなければ、 null を返します。

例1 ReflectionProperty::getType() の例

<?php
class User
{
public
string $name;
}

$rp = new ReflectionProperty('User', 'name');
echo
$rp->getType()->getName();
?>

上の例の出力は以下となります。

string

参考

add a note add a note

User Contributed Notes 2 notes

up
7
email at dronov dot vg
4 years ago
class User
{
    /**
     * @var string
     */
    public $name;
}

function getTypeNameFromAnnotation(string $className, string $propertyName): ?string
{
    $rp = new \ReflectionProperty($className, $propertyName);
    if (preg_match('/@var\s+([^\s]+)/', $rp->getDocComment(), $matches)) {
        return $matches[1];
    }
   
    return null;
}
   
echo getTypeNameFromAnnotation('User', 'name');

// string
up
0
andr3medeiros at gmail dot com
4 years ago
<?php

namespace App\Traits;

use
ReflectionClass;
use
Illuminate\Support\Str;
use
InvalidArgumentException;

trait
FieldTypeTrait {
 
  protected function
getType(String $field, ReflectionClass $reflectedClass = null)
  {
    if(
is_null($reflectedClass)) {
     
$reflectedClass = new ReflectionClass($this);
    }

    if (
$reflectedClass->hasProperty($field)) {
      return
$this->getFieldType($field, $reflectedClass);
    }

    return
null;
  }

  protected function
enumValue(String $field) {
    if(
$this->isEnum($field)) {
      throw new
InvalidArgumentException("'$field' is not an enum");
    }

   
$type = $this->getType($field);
   
$enumClass = $type->name;

    return new
$enumClass($this->{$field});
  }

  protected function
isEnum(String $field)
  {
   
$type = $this->getType($field);

    if(!
is_object($type)) {
      return
false;
    }

   
$className = $type->name;

   
$reflectedClass = new ReflectionClass($className);
   
$reflectedParent = $reflectedClass->getParentClass();

    return
$reflectedParent->getName() == 'MyCLabs\Enum\Enum';
  }

  private function
getUseStatements(): array
  {
   
$reflectedThis = new ReflectionClass($this);
   
$contents = file_get_contents($reflectedThis->getFileName());

   
$matches = [];

   
preg_match_all("/use ([\w\\\\]+)( as \w+)*/", $contents, $matches);

   
$results = [];
    foreach (
$matches[1] as $index => $value) {
     
$results[] = [
       
'namespace' => $value,
       
'alias' => isset($matches[2][$index]) ? str_replace(' as ', '', $matches[2][$index]) : null
     
];
    }

    return
$results;
  }

  private function
getFieldType(String $field, ReflectionClass $reflectedClass)
  {
   
$docComment = $reflectedClass->getProperty($field)->getDocComment();
   
$type = $this->getFieldTypeByFieldDocComment($docComment);

    if (!
is_object($type)) {
     
$fromClass = $this->getTypeByClassDocComment($field, $reflectedClass->getDocComment());
     
      if(
is_object($fromClass)) {
          return
$fromClass;
      }
    }

    return
$type;
  }

  private function
getFieldTypeByFieldDocComment(String $docComment)
  {
   
$matches = [];

    if (
preg_match("/\@var (\w+)(\[\])*/", $docComment, $matches) === 1) {

      if (
count($matches) > 0) {
       
$type = $matches[1];
       
$isArray = isset($matches[2]);
       
$fullyQualifiedName = $this->getFullyQualifiedName($type);

        if (
class_exists($fullyQualifiedName)) {
          return (object) [
           
'name' => $fullyQualifiedName,
           
'array' => $isArray
         
];
        }
      }

      return
$type;
    }
  }

  private function
getTypeByClassDocComment(String $field, String $docComment)
  {
   
$matches = [];

    if (
preg_match_all("/\@property (\w+) (\\$\w+)/", $docComment, $matches) > 0) {
     
$type = null;
     
$isArray = false;

      foreach (
$matches[2] as $index => $value) {
        if(
$value == $field) {
         
$type = $matches[1][$index];
         
$isArray = Str::endsWith($type, '[]');
         
$type = str_replace('[]', '', $type);
        }
      }

      if (
$type) {
       
$fullyQualifiedName = $this->getFullyQualifiedName($type);

        if (
class_exists($fullyQualifiedName)) {
          return (object) [
           
'name' => $fullyQualifiedName,
           
'array' => $isArray
         
];
        }
      }

      return
$type;
    }
  }

  private function
getFullyQualifiedName($className)
  {
   
$useStatements = collect($this->getUseStatements());
   
$aliasedStatement = $useStatements->where('alias', $className);

    if (
$aliasedStatement) {
      return
$aliasedStatement['namespace'];
    }

   
$statement = $useStatements->first(function ($statement) use ($className) {
      return
Str::endsWith($statement['namespace'], $className);
    });

    if (
$statement) {
      return
$statement['namespace'];
    }

    return
null;
  }
}
To Top