<?php
命名空间 App\Traits;
使用 ReflectionClass;
使用 Illuminate\Support\Str;
使用 InvalidArgumentException;
特质 FieldTypeTrait {
保护函数 getType(字符串 $field, ReflectionClass $reflectedClass = null)
{
如果(is_null($reflectedClass)) {
$reflectedClass = 新 ReflectionClass($this);
}
如果 ($reflectedClass->hasProperty($field)) {
返回 $this->getFieldType($field, $reflectedClass);
}
返回 null;
}
保护函数 enumValue(字符串 $field) {
如果($this->isEnum($field)) {
抛出 新 InvalidArgumentException("'$field' 不是枚举");
}
$type = $this->getType($field);
$enumClass = $type->name;
返回 新 $enumClass($this->{$field});
}
保护函数 isEnum(字符串 $field)
{
$type = $this->getType($field);
如果(!is_object($type)) {
返回 false;
}
$className = $type->name;
$reflectedClass = 新 ReflectionClass($className);
$reflectedParent = $reflectedClass->getParentClass();
返回 $reflectedParent->getName() == 'MyCLabs\Enum\Enum';
}
私有函数 getUseStatements(): 数组
{
$reflectedThis = 新 ReflectionClass($this);
$contents = file_get_contents($reflectedThis->getFileName());
$matches = [];
preg_match_all("/use ([\w\\\\]+)( as \w+)*/", $contents, $matches);
$results = [];
遍历 ($matches[1] 作为 $index => $value) {
$results[] = [
'namespace' => $value,
'alias' => isset($matches[2][$index]) ? str_replace(' as ', '', $matches[2][$index]) : null
];
}
返回 $results;
}
私有函数 getFieldType(字符串 $field, ReflectionClass $reflectedClass)
{
$docComment = $reflectedClass->getProperty($field)->getDocComment();
$type = $this->getFieldTypeByFieldDocComment($docComment);
如果 (!is_object($type)) {
$fromClass = $this->getTypeByClassDocComment($field, $reflectedClass->getDocComment());
如果(is_object($fromClass)) {
返回 $fromClass;
}
}
返回 $type;
}
私有函数 getFieldTypeByFieldDocComment(字符串 $docComment)
{
$matches = [];
如果 (preg_match("/\@var (\w+)(\[\])*/", $docComment, $matches) === 1) {
如果 (count($matches) > 0) {
$type = $matches[1];
$isArray = isset($matches[2]);
$fullyQualifiedName = $this->getFullyQualifiedName($type);
如果 (class_exists($fullyQualifiedName)) {
返回 (对象) [
'name' => $fullyQualifiedName,
'array' => $isArray
];
}
}
返回 $type;
}
}
私有函数 getTypeByClassDocComment(字符串 $field, 字符串 $docComment)
{
$matches = [];
如果 (preg_match_all("/\@property (\w+) (\\$\w+)/", $docComment, $matches) > 0) {
$type = null;
$isArray = false;
遍历 ($matches[2] 作为 $index => $value) {
如果($value == $field) {
$type = $matches[1][$index];
$isArray = Str::endsWith($type, '[]');
$type = str_replace('[]', '', $type);
}
}
如果 ($type) {
$fullyQualifiedName = $this->getFullyQualifiedName($type);
如果 (class_exists($fullyQualifiedName)) {
返回 (对象) [
'name' => $fullyQualifiedName,
'array' => $isArray
];
}
}
返回 $type;
}
}
私有函数 getFullyQualifiedName($className)
{
$useStatements = collect($this->getUseStatements());
$aliasedStatement = $useStatements->where('alias', $className);
如果 ($aliasedStatement) {
返回 $aliasedStatement['namespace'];
}
$statement = $useStatements->first(function ($statement) 使用 ($className) {
返回 Str::endsWith($statement['namespace'], $className);
});
如果 ($statement) {
返回 $statement['namespace'];
}
返回 null;
}
}