PHP 8.3.0 RC 6 available for testing

ReflectionProperty::getType

(PHP 7 >= 7.4.0, PHP 8)

ReflectionProperty::getTypeGets a property's type

说明

public ReflectionProperty::getType(): ?ReflectionType

Gets the associated type of a property.

参数

此函数没有参数。

返回值

Returns a ReflectionType if the property has a type, and null otherwise.

示例

示例 #1 ReflectionProperty::getType() example

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

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

以上示例会输出:

 
string

参见

add a note

User Contributed Notes 2 notes

up
6
email at dronov dot vg
3 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
-4
andr3medeiros at gmail dot com
3 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