note 125246 added to reflectionproperty.gettype
| From: | andr3medeiros at gmail dot com | Date: | Thu, 06 Aug 2020 10:31:04 +0000 |
| Subject: | note 125246 added to reflectionproperty.gettype | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-214931@lists.php.net to get a copy of this message | ||
<?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;
}
}
----
Server IP: 45.112.84.4
Probable Submitter: 177.234.144.170 (proxied: 177.124.48.110)
----
Manual Page -- http://php.net/manual/en/reflectionproperty.gettype.php
Edit -- https://master.php.net/note/edit/125246
Del: integrated -- https://master.php.net/note/delete/125246/integrated
Del: useless -- https://master.php.net/note/delete/125246/useless
Del: bad code -- https://master.php.net/note/delete/125246/bad+code
Del: spam -- https://master.php.net/note/delete/125246/spam
Del: non-english -- https://master.php.net/note/delete/125246/non-english
Del: in docs -- https://master.php.net/note/delete/125246/in+docs
Del: other reasons-- https://master.php.net/note/delete/125246
Reject -- https://master.php.net/note/reject/125246
Search -- https://master.php.net/manage/user-notes.php