Symfony 4 自定义注解问题 @ORM\Entity 不存在
Symfony 4 Custom annotation problem @ORM\Entity does not exist
作为我不久后发布的 CMS 开发的一部分 .. 我遇到了一个问题。
错误:
[Semantical Error] The annotation "@Doctrine\ORM\Mapping\Entity" in class ScyLabs\GiftCodeBundle\Entity\GiftCode does not exist, or could not be auto-loaded.
我给你解释一下,
基本上,在项目中,一切都是Overridable,已经是这样了,配置在文件services.yaml.
出于明显的简单性和迫切需要,允许我创建第二个继承自它的包。我告诉自己做我的 "Override" 或对项目说:"Hello here I am, I am a class uses me" 使用注释非常方便(而且更清晰)。
所以,我创建了一个自定义注释(到目前为止一切顺利..)你可以在这里找到..
<?php
/**
* Created by PhpStorm.
* User: alex
* Date: 04/11/2019
* Time: 14:25
*/
namespace ScyLabs\NeptuneBundle\Annotation\ScyLabsNeptune;
/**
* @Annotation
* @Target({"CLASS"})
* @Attributes({
* @Attribute("key",type="string"),
* @Attribute("classNameSpace",type="string"),
* })
*/
class Override
{
/**
* @var string
*/
public $key;
/**
* @var string
*/
public $classNameSpace;
public function __construct(array $opts) {
$this->key = $opts['value'];
$this->classNameSpace = $opts['class'];
}
}
嗯,我的注释已经到位了,我现在将它放在一个实体中,..就像这里
<?php
/**
* Created by PhpStorm.
* User: alex
* Date: 05/11/2019
* Time: 10:20
*/
namespace ScyLabs\GiftCodeBundle\Entity;
use ScyLabs\NeptuneBundle\Annotation\ScyLabsNeptune;
use Doctrine\ORM\Mapping as ORM;
/**
* @ScyLabsNeptune\Override("gift",class="ScyLabs\GiftCodeBundle\Entity\GiftCode")
* @ORM\Entity()
*/
class GiftCode
{
}
为什么要这样做?事实上,海王星中的一切都是自动化的,除了特殊情况,它会自动生成实体正常运行所需的所有 URL(添加/编辑/删除/列表)......为此,它必须指示该实体存在的项目,并且它必须是该系统的一部分。
所以,直到现在我在services.yaml中使用了一个非常完整的配置,其中我填充了一个table keys => value,对应于"key" => "Namespace"
以我为例:"gift" => "ScyLabs \ GiftCodeBundle \ Entity \ GiftCode"
总之,突然,对于override,我在一个编译步骤中做了一个处理
<?php
/**
* Created by PhpStorm.
* User: alex
* Date: 01/08/2018
* Time: 09:46
*/
namespace ScyLabs\NeptuneBundle;
class ScyLabsNeptuneBundle extends Bundle
{
public function getContainerExtension()
{
// Compilation de l'extension
return new ScyLabsNeptuneExtension();
}
}
在这个扩展中,我有这段代码可以让一切变得更好
$bundles = require $projectDir.'/config/bundles.php';
foreach ($bundles as $bundle => $env){
if($bundle === ScyLabsNeptuneBundle::class)
continue;
if(method_exists(new $bundle,'getParent') && (new $bundle)->getParent() === ScyLabsNeptuneBundle::class){
$reader = new AnnotationReader();
$reflClass = new \ReflectionClass(GiftCode::class);
$classAnotations = $reader->getClassAnnotation($reflClass,"Override");
foreach ($classAnotations as $classAnotation){
if($classAnotation instanceof Override && class_exists($classAnotation->classNameSpace)){
$config['override'][$classAnotation->key] = $classAnotation->classNameSpace; }
}
}
}
经过大量研究我怀疑,在我的扩展编译阶段,@ORM\Entity,和//Autowire,似乎还没有编译。
问题是突然间,当我得到我的个人注解(Override)时,我无法恢复@ORM \ Entity,我也不一定能删除它,因为它不再作为一个实体工作。
为什么要在这里这样做?因为后面我还有一步comoilation(A CompilationPass)
$container->addCompilerPass(new ResolveDoctrineTargetEntitiesPass(),PassConfig::TYPE_BEFORE_OPTIMIZATION,1000);
谁,根据我寄给他的画(你知道,我之前定义的那幅画)重新定义了学说将调用的实体。
有了这个我就可以覆盖具有相同名称的实体。
怎么办?? ..我承认我不能做更多...
在此先感谢朋友们;)
默认情况下,注释 reader 不使用与 classes 相同的自动加载器。
你需要告诉他如何像这样加载注释 class :
AnnotationRegistry::registerUniqueLoader('class_exists');
感谢您的回复。
但它不起作用,此功能已弃用并从 Annotations 2.0 中删除。
但是,当我尝试时,我找到了解决方案。
当我按照你的 link 并尝试页面中的代码时,我尝试了这个功能
AnnotationRegistry#registerFile($file)
获取@ORM\Entity文件路径,我使用
new \ReflectionClass(ORM\Entity::class);
而且,这项工作。
我删除了 AnnotationRegistry#registerFile($file)
功能,现在可以使用了。
感谢您的帮助;)
你是最棒的
作为我不久后发布的 CMS 开发的一部分 .. 我遇到了一个问题。
错误:
[Semantical Error] The annotation "@Doctrine\ORM\Mapping\Entity" in class ScyLabs\GiftCodeBundle\Entity\GiftCode does not exist, or could not be auto-loaded.
我给你解释一下,
基本上,在项目中,一切都是Overridable,已经是这样了,配置在文件services.yaml.
出于明显的简单性和迫切需要,允许我创建第二个继承自它的包。我告诉自己做我的 "Override" 或对项目说:"Hello here I am, I am a class uses me" 使用注释非常方便(而且更清晰)。
所以,我创建了一个自定义注释(到目前为止一切顺利..)你可以在这里找到..
<?php
/**
* Created by PhpStorm.
* User: alex
* Date: 04/11/2019
* Time: 14:25
*/
namespace ScyLabs\NeptuneBundle\Annotation\ScyLabsNeptune;
/**
* @Annotation
* @Target({"CLASS"})
* @Attributes({
* @Attribute("key",type="string"),
* @Attribute("classNameSpace",type="string"),
* })
*/
class Override
{
/**
* @var string
*/
public $key;
/**
* @var string
*/
public $classNameSpace;
public function __construct(array $opts) {
$this->key = $opts['value'];
$this->classNameSpace = $opts['class'];
}
}
嗯,我的注释已经到位了,我现在将它放在一个实体中,..就像这里
<?php
/**
* Created by PhpStorm.
* User: alex
* Date: 05/11/2019
* Time: 10:20
*/
namespace ScyLabs\GiftCodeBundle\Entity;
use ScyLabs\NeptuneBundle\Annotation\ScyLabsNeptune;
use Doctrine\ORM\Mapping as ORM;
/**
* @ScyLabsNeptune\Override("gift",class="ScyLabs\GiftCodeBundle\Entity\GiftCode")
* @ORM\Entity()
*/
class GiftCode
{
}
为什么要这样做?事实上,海王星中的一切都是自动化的,除了特殊情况,它会自动生成实体正常运行所需的所有 URL(添加/编辑/删除/列表)......为此,它必须指示该实体存在的项目,并且它必须是该系统的一部分。
所以,直到现在我在services.yaml中使用了一个非常完整的配置,其中我填充了一个table keys => value,对应于"key" => "Namespace"
以我为例:"gift" => "ScyLabs \ GiftCodeBundle \ Entity \ GiftCode"
总之,突然,对于override,我在一个编译步骤中做了一个处理
<?php
/**
* Created by PhpStorm.
* User: alex
* Date: 01/08/2018
* Time: 09:46
*/
namespace ScyLabs\NeptuneBundle;
class ScyLabsNeptuneBundle extends Bundle
{
public function getContainerExtension()
{
// Compilation de l'extension
return new ScyLabsNeptuneExtension();
}
}
在这个扩展中,我有这段代码可以让一切变得更好
$bundles = require $projectDir.'/config/bundles.php';
foreach ($bundles as $bundle => $env){
if($bundle === ScyLabsNeptuneBundle::class)
continue;
if(method_exists(new $bundle,'getParent') && (new $bundle)->getParent() === ScyLabsNeptuneBundle::class){
$reader = new AnnotationReader();
$reflClass = new \ReflectionClass(GiftCode::class);
$classAnotations = $reader->getClassAnnotation($reflClass,"Override");
foreach ($classAnotations as $classAnotation){
if($classAnotation instanceof Override && class_exists($classAnotation->classNameSpace)){
$config['override'][$classAnotation->key] = $classAnotation->classNameSpace; }
}
}
}
经过大量研究我怀疑,在我的扩展编译阶段,@ORM\Entity,和//Autowire,似乎还没有编译。
问题是突然间,当我得到我的个人注解(Override)时,我无法恢复@ORM \ Entity,我也不一定能删除它,因为它不再作为一个实体工作。
为什么要在这里这样做?因为后面我还有一步comoilation(A CompilationPass)
$container->addCompilerPass(new ResolveDoctrineTargetEntitiesPass(),PassConfig::TYPE_BEFORE_OPTIMIZATION,1000);
谁,根据我寄给他的画(你知道,我之前定义的那幅画)重新定义了学说将调用的实体。
有了这个我就可以覆盖具有相同名称的实体。
怎么办?? ..我承认我不能做更多...
在此先感谢朋友们;)
默认情况下,注释 reader 不使用与 classes 相同的自动加载器。 你需要告诉他如何像这样加载注释 class :
AnnotationRegistry::registerUniqueLoader('class_exists');
感谢您的回复。
但它不起作用,此功能已弃用并从 Annotations 2.0 中删除。
但是,当我尝试时,我找到了解决方案。
当我按照你的 link 并尝试页面中的代码时,我尝试了这个功能
AnnotationRegistry#registerFile($file)
获取@ORM\Entity文件路径,我使用
new \ReflectionClass(ORM\Entity::class);
而且,这项工作。
我删除了 AnnotationRegistry#registerFile($file)
功能,现在可以使用了。
感谢您的帮助;) 你是最棒的