【问题标题】:How to configure Doctrine Entity Annotation autoloading in User-defined symfony Bundle?如何在用户定义的 symfony Bundle 中配置 Doctrine Entity Annotation 自动加载?
【发布时间】:2017-10-29 03:20:51
【问题描述】:

当我尝试验证我的 symfony 架构时,我得到了错误:

[Doctrine\Common\Annotations\AnnotationException]                            
[Semantical Error] The annotation "@Doctrine\Orm\Mapping\Entity" in class C  
hill\EmailUser\Entity\EmailUser does not exist, or could not be auto-loaded 

我在这个问题中看到:Trouble with importing annotations,据说我们需要从 Doctrine Simple Annotation Reader 更改。尽管在自动加载器中进行捆绑配置似乎很奇怪,但我尝试通过 app/autoloader.php 进行配置:

use Doctrine\ORM\Configuration;

path = __DIR__."/../vendor/path/to/annotationDriver.php"
Configuration::newDefaultAnnotationDriver(path, false);

我也尝试过研究,看看是否可以找到类似的参数:

doctrine.orm.mappings.annotations.simple_annotations_reader

我可以设置为 false,但我找不到任何东西。

正如您将在下面看到的,我还尝试手动将我的包的映射添加到 config.yml 中的 ORM 设置。

composer.json:

{
    "name": "root/photoproject",
"license": "proprietary",
"type": "project",
"autoload": {
    "psr-4": {
        "": "src/"
    },
    "classmap": [
        "app/AppKernel.php",
        "app/AppCache.php"
    ]
},
"autoload-dev": {
    "files": [
        "vendor/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
    ]
},
"require": {
    "php": ">=5.3.9",
    "doctrine/annotations": "^1.4",
    "doctrine/doctrine-bundle": "~1.4",
    "doctrine/migrations": "^1.5",
    "doctrine/orm": "^2.5",
    "incenteev/composer-parameter-handler": "~2.0",
    "sensio/distribution-bundle": "~4.0",
    "sensio/framework-extra-bundle": "^3.0.2",
    "symfony/monolog-bundle": "^3.0.2",
    "symfony/swiftmailer-bundle": "~2.3,>=2.3.10",
    "symfony/symfony": "2.8.*",
    "twig/twig": "^1.0||^2.0"
},
"require-dev": {
    "sensio/generator-bundle": "~3.0",
    "symfony/phpunit-bridge": "~2.7"
},
"scripts": {
    "symfony-scripts": [
        "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
    ],
    "post-install-cmd": [
        "@symfony-scripts"
    ],
    "post-update-cmd": [
        "@symfony-scripts"
    ]
},
"config": {
    "bin-dir": "bin",
    "sort-packages": true
},
"extra": {
    "symfony-app-dir": "app",
    "symfony-web-dir": "web",
    "symfony-assets-install": "relative",
    "incenteev-parameters": {
        "file": "app/config/parameters.yml"
    },
    "branch-alias": null
}
}

app/config/config.yml

imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }

# Put parameters here that don't need to change on each machine where the app is deployed
# http://symfony.com/doc/current/best_practices    /configuration.html#application-related-configuration
parameters:
locale: en

    framework:
#esi: ~
#translator: { fallbacks: ['%locale%'] }
secret: '%secret%'
router:
    resource: '%kernel.root_dir%/config/routing.yml'
    strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
serializer: { enable_annotations: true }
templating:
    engines: ['twig']
default_locale: '%locale%'
trusted_hosts: ~
trusted_proxies: ~
session:
    # handler_id set to null will use default session handler from php.ini
    handler_id: ~
fragments: ~
http_method_override: true

    # Twig Configuration
    twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
    # Doctrine Configuration
    doctrine:
dbal:
    driver: pdo_mysql
    host: '%database_host%'
    port: '%database_port%'
    dbname: '%database_name%'
    user: '%database_user%'
    password: '%database_password%'
    charset: UTF8
    # if using pdo_sqlite as your database driver:
    #   1. add the path in parameters.yml
    #     e.g. database_path: '%kernel.root_dir%/data/data.db3'
    #   2. Uncomment database_path in parameters.yml.dist
    #   3. Uncomment next line:
    #path: '%database_path%'

orm:
    auto_generate_proxy_classes: '%kernel.debug%'
    entity_managers:
        default:
            naming_strategy: doctrine.orm.naming_strategy.underscore
            auto_mapping: true
            mappings:
                ChillEmailUserBundle: ~

    # Swiftmailer Configuration
    swiftmailer:
transport: '%mailer_transport%'
hostity/l: { type: memory }

src/Chill/EmailUserBundle/Entity/EmailUser.php

namespace Chill\EmailUser\Entity;

use Doctrine\Orm\Mapping as ORM;
use Symfony\Component\Validator\Contraints as Assert;

/**
 * @ORM\Entity
 */

class EmailUser
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length="1023")
     * @Assert\Email(message="Not a valid email")
     */
    private $email;

    /**
     * @ORM\Column(type="string", length="4096")
     */
    private $password;

    /**
     * @ORM\Column(type="string", length="4096")
     */
    private $salt;

    /**
     * @ORM\ManyToMany(targetEntity="Role")
     */
    private $roles;
}

所以我的问题是我怎样才能按照 Symfony 中公认的答案的建议去做(同时最好保持包相对可重用)。

谢谢


<?php

use Doctrine\Common\Annotations\AnnotationRegistry;
use Composer\Autoload\ClassLoader;

/** @var ClassLoader $loader */
$loader = require __DIR__.'/../vendor/autoload.php';
AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
return $loader;                            

【问题讨论】:

    标签: php symfony doctrine


    【解决方案1】:

    AFAIK 你必须为AnnotationRegistry注册加载器。

    更详细的文档是available here。对于 symfony 项目,最简单的方法是使用 app/autoload 并包含以下内容:

    <?php
    
    use Composer\Autoload\ClassLoader;
    use Doctrine\Common\Annotations\AnnotationRegistry;
    
    /**
     * @var ClassLoader $loader
     */
    $loader = require __DIR__.'/../vendor/autoload.php';
    
    AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
    
    return $loader;
    

    由于这种需要,bundle 通常使用 XML 配置容器、路由器等。

    如果您更喜欢注释并且那是您的私有包,只需注册加载程序,如上所示。如果你想公开,我建议配置xmls。

    【讨论】:

    • 感谢您的快速回复。我更新了我的 app/autoload.php 并将其添加到问题中,但我仍然看到错误。我想我可能只需要切换到 XML。
    • 这就是 Doctrine Annotations 通过全局注册表使用自己的自动加载机制的原因。如果您想知道注解注册表是全局的,那么没有其他方法可以直接解决自动加载注解类的架构问题。此外,如果您考虑 PHP 自动加载,那么您会认识到它也是全局的。”所以我认为您的答案是正确的,“不要”。我只需要使用 XML。
    • 您确定您的bin/console 使用app/autoload 吗?还有一些随机的想法:用Doctrine\ORM\Mapping(区分大小写)替换Doctrine\Orm\Mapping,清除缓存(您的控制台可能使用prod env 并缓存注释)。您如何验证架构?
    • Grrr。毕竟是小写的 Orm。谢谢
    • 发生了,很高兴你度过了难关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 2014-05-03
    • 2019-10-26
    • 2022-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多