Reflection API를 알게 된 방법
Doctrine
를 사용하는 것이 절대적으로 가능하지만 Framework-X가 승격하는 반응 방식이 아닙니다. 그래서 이것은 데이터베이스와 통신하는 보다 "실제적인"접근 방식을 탐구하기 위해 Doctrine의 알려진 근거를 떠나게 했습니다.그래서 나는 어쨌든.
저로서, 저는 새로운 주제를 탐구하고 현재 능력으로 얼마나 갈 수 있는지 확인하는 것을 좋아합니다. 나는 내가 한 모든 것이 거의 독점적으로 "객체 지향"이었던 배경에서 왔지만 지금은
Doctrine
(인기있는 PHP ORM ) 없이 남겨졌습니다. 비슷한 (그러나 훨씬 더 단순한) 내 자신의 기능.나는 내 프로젝트에서 미니 ORM을 구축할 것이라고 생각하지 않았지만 그것이 내가 나 자신을 발견한 곳입니다. 나는 엔터티 클래스 또는 "일반 PHP 개체"(POPO)로 설명할 수 있는 항목이 있습니다. 이러한 POPO는 유형을 사용하여 고유한 속성을 설명합니다. 이러한 유형은 다른 클래스(다대일)의 배열로 반영되는 일대다 관계뿐만 아니라 다른 엔터티에 대한 관계를 설명할 수 있습니다. 현재 프로젝트에서 다대다 관계가 없습니다. 따라서 POPO는 다음과 같이 보일 수 있습니다.
<?php
namespace App\Entity;
class Category
{
/**
* @var string $uuid - UUID version 4 variant 1
*/
private string $uuid = '';
private string $name = '';
/**
* @var Category[] $childCategories
*/
private array $childCategories = [];
private ?Category $parentCategory = null;
public function setUuid(string $uuid = ''): self
{
$this->uuid = $uuid;
return $this;
}
public function getUuid(): string
{
return $this->uuid;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getName(): string
{
return $this->name;
}
public function setChildCategories(array $childCategories): self
{
$this->childCategories = $childCategories;
return $this;
}
public function getChildCategories(): array
{
return $this->childCategories;
}
public function addChildCategory(Category $childCategory): self
{
if (!$this->hasChildCategory($childCategory)){
$this->childCategories[] = $childCategory;
}
return $this;
}
public function removeChildCategory(Category $childCategory): self
{
$this->childCategories = array_filter($this->childCategories, function ($category) use ($childCategory) {
return $category->getUuid() !== $childCategory->getUuid();
});
return $this;
}
public function hasChildCategory(Category $childCategory): bool
{
return in_array($childCategory, $this->childCategories);
}
public function setParentCategory(Category $parentCategory): self
{
$parentCategory->addChildCategory($this);
$this->parentCategory = $parentCategory;
return $this;
}
public function getParentCategory(): ?Category
{
return $this->parentCategory;
}
}
이와 같은 POPO를 사용하면 이러한 개체를 데이터베이스에 저장할 수 있을 뿐만 아니라 데이터베이스에서 결과를 가져와 개체로 되돌릴 수 있기를 원했습니다. 이것이 나를 위해 작동하려면 각 속성이 어떤 유형인지 알아야 했습니다. 배열의 경우 배열 내부에 있는 객체의 유형을 알아야 했습니다. 일반 속성에는 단순히 명시된 유형이 있습니다. 배열의 경우
@var
주석을 사용합니다. /**
* @var Category[] $childCategories
*/
private array $childCategories = [];
각 속성에 대해 getter와 setter도 있습니다. 이 모든 것을 알면 데이터베이스에 저장하려고 할 때 모든 관련 속성을 얻을 수 있습니다. 클래스에 대한 충분한 통찰력을 통해 각 속성을 해당 SQL 유형으로 바꿀 수 있습니다. 예를 들어 MySQL의 경우 문자열을
VARCHAR
로, 참조를 (UUID를 사용하는 경우) VARCHAR
로 변환할 수 있습니다. 열쇠.그러나 관련 통찰력은 어디서 얻습니까?!
그것은
ReflectionClass
일 것입니다! 그것 없이는 각 클래스 파일을 한 줄씩 구문 분석해야 하지만 대신 getMethods
, getProperties
, getType
, getDocComment
사용할 수 있습니다. 이 프로젝트에서 가장 재미있었던 것은 배열에 대한 주석 유형 힌트를 가져오는 것이었습니다. 그것들을 가져오기 위해 유틸리티 클래스에 메소드를 만들었습니다.
// Inside a class called App\Utility\EntityReflection.php
public static function getPropertyTypeFromComment(string $entityClass, string $property): ?string
{
$reflectionClass = new \ReflectionClass($entityClass);
$reflectionProperty = $reflectionClass->getProperty($property);
$propertyComment = $reflectionProperty->getDocComment();
$refType = preg_grep('/([A-Z])\w+/', explode(" ", $propertyComment));
if (count($refType) > 0) {
$refType = array_pop($refType);
} else {
return null;
}
if ($refType === null) {
return null;
}
if (strpos($refType, '[]') !== false) {
return $refType;
}
return null;
}
이것을
$commentType = EntityReflection::getPropertyTypeFromComment(Category::class, 'categories');
로 호출하면 Category[]
가 반환됩니다.그리고 그것이 내가 Reflection API를 우연히 발견한 방법입니다. 이제 관계형 데이터베이스에서 개체를 성공적으로 저장하고 가져오는 데 사용합니다. 하지만 그건 다른 이야기입니다. 그래서 당신은 당신의 물건에 반사를 사용한 적이 있고, 어떻게 그것을 좋아했습니까? 내가 암시했을지도 모르지만, 나는 그것이 꽤 재미있고 마술적이며 매우 유용하다는 것을 알았습니다!
Reference
이 문제에 관하여(Reflection API를 알게 된 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/andersbjorkland/how-i-stumbled-onto-the-reflection-api-443m텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)