Symfony 和 Sonata 的 ReflectionException,"Class does not exist"

ReflectionException with Symfony and Sonata, "Class does not exist"

我在尝试将我的实体放入 Sonata Admin Bundle 时遇到问题。我有大约 5 个实体,它们在捆绑包中被详细列出和查看,但我无法编辑或创建新条目。

当我尝试编辑或创建时,出现 ReflectionException 错误:

Class does not exist

为了解决这个问题,我尝试对名称空间进行操作(将控制器移动到与管理文件相同的名称空间中,或者调整管理控制器以告知它我的实体(“->添加('individual', 'entity', array('class' => 'Platform\ProjectBundle\Entity\Individual'))" 而不是 ->add('individual')).

我的实体名为 Biosample。这是实体文件:

<?php

namespace Platform\ProjectBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
* @ORM\Entity
* @ORM\Table(name="biosample")
*/
class Biosample
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
 protected $id;

/**
 * @ORM\ManyToOne(targetEntity="Individual", inversedBy="samples")
 * @ORM\JoinColumn(name="individual_id", referencedColumnName="id")
 */
 protected $individual;

/**
 * @ORM\Column(type="string", length=100)
 */
 protected $organ;

 /**
 * @ORM\Column(type="string", length=100)
 */
 protected $sample_name;

/**
 * @ORM\Column(type="string", nullable=true)
 */
 protected $organ_location;

/**
 * @ORM\Column(type="string")
 */
 protected $tissue_type;

/**
 * @ORM\Column(type="string", nullable=true)
 */
 protected $tissue_subtype;

/**
 * @ORM\Column(type="datetimetz")
 */
 protected $sampling_date;

/**
 * @ORM\Column(type="decimal", scale=3, nullable=true)
 */
 protected $cellularity;

/**
 * @ORM\Column(type="string", nullable=true)
 */
 protected $conservation;

/**
 * @ORM\Column(type="text", nullable=true)
 */
 protected $description;

/**
 * @ORM\ManyToMany(targetEntity="Project", mappedBy="biosamples")
 */
 protected $projects;

 public function __construct()
 {
      $this->projects = new ArrayCollection();
 }

 public function __toString()
 {
      return $this->sample_name;
 }

/**
 * Get id
 *
 * @return integer 
 */

public function getId()
{
    return $this->id;
}

/**
 * Set organ
 *
 * @param string $organ
 * @return Biosample
 */
public function setOrgan($organ)
{
    $this->organ = $organ;

    return $this;
}

/**
 * Get organ
 *
 * @return string 
 */
public function getOrgan()
{
    return $this->organ;
}

/**
 * Set organ_location
 *
 * @param string $organLocation
 * @return Biosample
 */
public function setOrganLocation($organLocation)
{
    $this->organ_location = $organLocation;

    return $this;
}

/**
 * Get organ_location
 *
 * @return string 
 */
public function getOrganLocation()
{
    return $this->organ_location;
}

/**
 * Set tissue_type
 *
 * @param string $tissueType
 * @return Biosample
 */
public function setTissueType($tissueType)
{
    $this->tissue_type = $tissueType;

    return $this;
}

/**
 * Get tissue_type
 *
 * @return string 
 */
public function getTissueType()
{
    return $this->tissue_type;
}

/**
 * Set tissue_subtype
 *
 * @param string $tissueSubtype
 * @return Biosample
 */
public function setTissueSubtype($tissueSubtype)
{
    $this->tissue_subtype = $tissueSubtype;

    return $this;
}

/**
 * Get tissue_subtype
 *
 * @return string 
 */
public function getTissueSubtype()
{
    return $this->tissue_subtype;
}

/**
 * Set sampling_date
 *
 * @param \DateTime $samplingDate
 * @return Biosample
 */
public function setSamplingDate($samplingDate)
{
    $this->sampling_date = $samplingDate;

    return $this;
}

/**
 * Get sampling_date
 *
 * @return \DateTime 
 */
public function getSamplingDate()
{
    return $this->sampling_date;
}

/**
 * Set cellularity
 *
 * @param string $cellularity
 * @return Biosample
 */
public function setCellularity($cellularity)
{
    $this->cellularity = $cellularity;

    return $this;
}

/**
 * Get cellularity
 *
 * @return string 
 */
public function getCellularity()
{
    return $this->cellularity;
}

/**
 * Set conservation
 *
 * @param string $conservation
 * @return Biosample
 */
public function setConservation($conservation)
{
    $this->conservation = $conservation;

    return $this;
}

/**
 * Get conservation
 *
 * @return string 
 */
public function getConservation()
{
    return $this->conservation;
}

/**
 * Set description
 *
 * @param string $description
 * @return Biosample
 */
public function setDescription($description)
{
    $this->description = $description;

    return $this;
}

/**
 * Get description
 *
 * @return string 
 */
public function getDescription()
{
    return $this->description;
}

/**
 * Set individual
 *
 * @param \Platform\ProjectBundle\Entity\Individual $individual
 * @return Biosample
 */
public function setIndividual(\Platform\ProjectBundle\Entity\Individual $individual = null)
{
    $this->individual = $individual;

    return $this;
}

/**
 * Get individual
 *
 * @return \Platform\ProjectBundle\Entity\Individual 
 */
public function getIndividual()
{
    return $this->individual;
}

/**
 * Add projects
 *
 * @param \Platform\ProjectBundle\Entity\Project $projects
 * @return Biosample
 */
public function addProject(\Platform\ProjectBundle\Entity\Project $projects)
{
    $this->projects[] = $projects;

    return $this;
}

/**
 * Remove projects
 *
 * @param \Platform\ProjectBundle\Entity\Project $projects
 */
public function removeProject(\Platform\ProjectBundle\Entity\Project $projects)
{
    $this->projects->removeElement($projects);
}

/**
 * Get projects
 *
 * @return \Doctrine\Common\Collections\Collection 
 */
public function getProjects()
{
    return $this->projects;
}

/**
 * Set sample_name
 *
 * @param string $sampleName
 * @return Biosample
 */
public function setSampleName($sampleName)
{
    $this->sample_name = $sampleName;

    return $this;
}

/**
 * Get sample_name
 *
 * @return string 
 */
public function getSampleName()
{
    return $this->sample_name;
}
}`

这是我的 BiosampleAdmin.php:

    <?php

namespace Platform\ProjectBundle\Controller\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;

use Knp\Menu\ItemInterface as MenuItemInterface;

use Platform\ProjectBundle\Entity\Biosample;

class BiosampleAdmin extends Admin
{

    /**
     * @param \Sonata\AdminBundle\Show\ShowMapper $showMapper
     *
     * @return void
     */
    protected function configureShowFields(ShowMapper $showMapper)
    {
        $showMapper
            ->add('id')
            ->add('sample_name')
            ->add('individual', 'entity', array('class' => 'Platform\ProjectBundle\Entity\Individual'))
            ->add('organ')
            ->add('organ_location')
            ->add('tissue_type')
            ->add('tissue_subtype')
            ->add('sampling_date')
            ->add('cellularity')
            ->add('conservation')
            ->add('projects', 'entity', array('class' => 'Platform\ProjectBundle\Entity\Project'))
            ->add('description')
        ;
    }


    /**
     * @param \Sonata\AdminBundle\Form\FormMapper $formMapper
     *
     * @return void
     */
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->with('General')
                ->add('sample_name')
                ->add('individual')
                ->add('organ')
                ->add('organ_location')
                ->add('tissue_type')
                ->add('tissue_subtype')
            ->end()
            ->with('Miscelaneous')
                ->add('sampling_date')
                ->add('cellularity')
                ->add('conservation')
            ->end()
            ->with('Projects')
                ->add('projects')
            ->end()
            ->with('Description')
                ->add('description', 'sonata_type_model', array('multiple' => false))
            ->end()
        ;
    }

    /**
     * @param \Sonata\AdminBundle\Datagrid\ListMapper $listMapper
     *
     * @return void
     */
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('id')
            ->add('sample_name')
            ->add('individual')
            ->add('projects')
            ->add('organ')
            ->add('tissue')
            ->add('_action', 'actions', array(
                'actions' => array(
                    'show' => array(),
                    'edit' => array(),
                    'delete' => array(),
                )
            ))
        ;
    }


    /**
     * @param \Sonata\AdminBundle\Datagrid\DatagridMapper $datagridMapper
     *
     * @return void
     */
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('sample_name')
            ->add('individual')
            ->add('projects')
        ;
    }
}

这是管理控制器:

    <?php

namespace Platform\ProjectBundle\Controller;

use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Platform\ProjectBundle\Entity\Biosample;

class BiosampleAdminController extends Controller
{

}

如果你需要它,这里是我的 composer.json:

{
    "name": "symfony/framework-standard-edition",
    "license": "MIT",
    "type": "project",
    "description": "The \"Symfony Standard Edition\" distribution",
    "autoload": {
        "psr-0": { "": "src/", "SymfonyStandard": "app/" }
    },
    "require": {
        "php": ">=5.3.3",
        "symfony/symfony": "2.6.*",
        "doctrine/orm": "~2.2,>=2.2.3,<2.5",
        "doctrine/dbal": "<2.5",
        "doctrine/doctrine-bundle": "~1.2",
        "twig/extensions": "~1.0",
        "symfony/assetic-bundle": "~2.3",
        "symfony/swiftmailer-bundle": "~2.3",
        "symfony/monolog-bundle": "~2.4",
        "sensio/distribution-bundle": "~3.0,>=3.0.12",
        "sensio/framework-extra-bundle": "~3.0,>=3.0.2",
        "jms/security-extra-bundle": "~1.2",
        "ircmaxell/password-compat": "~1.0.3",
        "stof/doctrine-extensions-bundle": "~1.1@dev",
        "friendsofsymfony/user-bundle": "~1.3",
        "incenteev/composer-parameter-handler": "~2.0",
        "nervo/yuicompressor": "2.4.8",
        "sonata-project/admin-bundle": "~2.3",
        "sonata-project/doctrine-orm-admin-bundle": "~2.3",
        "sonata-project/easy-extends-bundle": "~2.1",
        "sonata-project/user-bundle": "~2.2",
        "knplabs/knp-menu-bundle": "~1.1",
        "mopa/bootstrap-bundle": "~2",
        "twbs/bootstrap-sass": "~3.3.0",
        "knplabs/knp-paginator-bundle": "dev-master",
        "knplabs/knp-menu": "~1.1",
        "craue/formflow-bundle": "~2.0"
    },
    "require-dev": {
        "sensio/generator-bundle": "~2.3"
    },
    "scripts": {
        "post-root-package-install": [
            "SymfonyStandard\Composer::hookRootPackageInstall"
        ],
        "post-install-cmd": [
            "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::removeSymfonyStandardFiles"
        ],
        "post-update-cmd": [
            "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::removeSymfonyStandardFiles"
        ]
    },
    "config": {
        "bin-dir": "bin"
    },
    "extra": {
        "symfony-app-dir": "app",
        "symfony-web-dir": "web",
        "symfony-assets-install": "relative",
        "incenteev-parameters": {
            "file": "app/config/parameters.yml"
        },
        "branch-alias": {
            "dev-master": "2.6-dev"
        }
    }
}

最后,这是我的服务声明和我的 config.yml 文件: Service.yml:

services:
    platform.project.admin.biosample:
        class: Platform\ProjectBundle\Controller\Admin\BiosampleAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, group: Project Manager, label: Biosample }
        arguments: [null, Platform\ProjectBundle\Entity\Biosample, PlatformProjectBundle:BiosampleAdmin]

Config.yml:

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

framework:
    #esi:             ~
    translator:      { fallbacks: ["%locale%"] }
    secret:          "%secret%"
    router:
        resource: "%kernel.root_dir%/config/routing.yml"
        strict_requirements: ~
    form:            ~
    csrf_protection: ~
    validation:      { enable_annotations: true }
    templating:
        engines: ['twig']
        #assets_version: SomeVersionScheme
    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%"

# Assetic Configuration
assetic:
    debug:          "%kernel.debug%"
    use_controller: false
    bundles:        [ ]
    #java: /usr/bin/java
    filters:
        cssrewrite: ~
        #closure:
        #    jar: "%kernel.root_dir%/Resources/java/compiler.jar"
        #yui_css:
        #    jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"

# Doctrine Configuration
doctrine:
    dbal:
        driver:   "%database_driver%"
        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%"
        types:
            json: Sonata\Doctrine\Types\JsonType
    orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        auto_mapping: true

# Swiftmailer Configuration
swiftmailer:
    transport: "%mailer_transport%"
    host:      "%mailer_host%"
    username:  "%mailer_user%"
    password:  "%mailer_password%"
    spool:     { type: memory }


fos_user:
    db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
    firewall_name: secured
    user_class: Application\Sonata\UserBundle\Entity\User
    group:
        group_class: Application\Sonata\UserBundle\Entity\Group
        group_manager: sonata.user.orm.group_manager

    service:
        user_manager: sonata.user.orm.user_manager


sonata_doctrine_orm_admin:
    entity_manager: ~

sonata_block:
    default_contexts: [cms]
    blocks:
        sonata.admin.block.admin_list:
            contexts: [admin]
        sonata.user.block.menu: ~
        sonata.user.block.account: ~
        sonata.block.service.text: ~


sonata_user:
    security_acl: true
    manager_type: orm

mopa_bootstrap:
    form: ~

最后但同样重要的是:完整的堆栈跟踪。

[1] ReflectionException: Class  does not exist
    at n/a
        in /var/www/Project/app/cache/dev/classes.php line 6756

    at ReflectionClass->__construct('')
        in /var/www/Project/app/cache/dev/classes.php line 6756

    at Doctrine\Common\Persistence\AbstractManagerRegistry->getManagerForClass(null)
        in /var/www/Project/vendor/sonata-project/doctrine-orm-admin-bundle/Model/ModelManager.php line 220

    at Sonata\DoctrineORMAdminBundle\Model\ModelManager->getEntityManager(null)
        in /var/www/Project/vendor/sonata-project/doctrine-orm-admin-bundle/Model/ModelManager.php line 54

    at Sonata\DoctrineORMAdminBundle\Model\ModelManager->getMetadata(null)
        in /var/www/Project/vendor/sonata-project/doctrine-orm-admin-bundle/Model/ModelManager.php line 317

    at Sonata\DoctrineORMAdminBundle\Model\ModelManager->getIdentifierFieldNames(null)
        in /var/www/Project/app/cache/dev/classes.php line 12663

    at Sonata\AdminBundle\Form\ChoiceList\ModelChoiceList->__construct(object(ModelManager), null, null, null, null)
        in /var/www/Project/app/cache/dev/classes.php line 13690

    at Sonata\AdminBundle\Form\Type\ModelType->Sonata\AdminBundle\Form\Type\{closure}(object(OptionsResolver), object(SimpleChoiceList))
        in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/OptionsResolver.php line 836

    at Symfony\Component\OptionsResolver\OptionsResolver->offsetGet('choice_list')
        in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/OptionsResolver.php line 769

    at Symfony\Component\OptionsResolver\OptionsResolver->resolve(array('sonata_field_description' => object(FieldDescription), 'class' => null, 'model_manager' => object(ModelManager), 'multiple' => false, 'label_render' => false, 'label' => 'Description'))
        in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/ResolvedFormType.php line 109

    at Symfony\Component\Form\ResolvedFormType->createBuilder(object(FormFactory), 'description', array('sonata_field_description' => object(FieldDescription), 'class' => null, 'model_manager' => object(ModelManager), 'multiple' => false, 'label_render' => false, 'label' => 'Description'))
        in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/DataCollector/Proxy/ResolvedTypeDataCollectorProxy.php line 82

    at Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy->createBuilder(object(FormFactory), 'description', array('sonata_field_description' => object(FieldDescription), 'class' => null, 'model_manager' => object(ModelManager), 'multiple' => false, 'label_render' => false, 'label' => 'Description'))
        in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/FormFactory.php line 87

    at Symfony\Component\Form\FormFactory->createNamedBuilder('description', 'sonata_type_model', null, array('sonata_field_description' => object(FieldDescription), 'class' => null, 'model_manager' => object(ModelManager), 'multiple' => false, 'label_render' => false, 'label' => 'Description'))
        in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php line 106

    at Symfony\Component\Form\FormBuilder->create('description', 'sonata_type_model', array('sonata_field_description' => object(FieldDescription), 'class' => null, 'model_manager' => object(ModelManager), 'multiple' => false, 'label_render' => false, 'label' => 'Description'))
        in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php line 268

    at Symfony\Component\Form\FormBuilder->resolveChildren()
        in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php line 216

    at Symfony\Component\Form\FormBuilder->getForm()
        in /var/www/Project/app/cache/dev/classes.php line 9671

    at Sonata\AdminBundle\Admin\Admin->buildForm()
        in /var/www/Project/app/cache/dev/classes.php line 9930

    at Sonata\AdminBundle\Admin\Admin->getForm()
        in /var/www/Project/vendor/sonata-project/admin-bundle/Controller/CRUDController.php line 353

    at Sonata\AdminBundle\Controller\CRUDController->editAction('1')
        in  line 

    at call_user_func_array(array(object(CRUDController), 'editAction'), array('1'))
        in /var/www/Project/app/bootstrap.php.cache line 3022

    at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), '1')
        in /var/www/Project/app/bootstrap.php.cache line 2984

    at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), '1', true)
        in /var/www/Project/app/bootstrap.php.cache line 3133

    at Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel->handle(object(Request), '1', true)
        in /var/www/Project/app/bootstrap.php.cache line 2377

    at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
        in /var/www/Project/web/app_dev.php line 28

好吧,这个错误的原因是教程中的错误 copy/paste。

在管理 Class 中,函数 configureFormFields 包含一个字段 "Description" 描述不当。

->with('Description')
                ->add('description', 'sonata_type_model', array('multiple' => false))
            ->end()

我不得不将其替换为:

  ->with('Description')
                ->add('description')
            ->end()

我发现自动 Admin Class 骨架生成是 Sonata Admin Bundle 的一个功能。 为了自动生成,执行:

php app/console sonata:admin:generate

然后输入实体的完整路径,在本例中:

Platform\ProjectBundle\Entity\Biosample

管理包将解析您的实体并:

  • 生成管理 Class 文件
  • 在您的应用程序包的 service.yml
  • 中添加一个条目
  • 生成可选的 CRUD 控制器

我想这应该是从 sonata admin bundle 开始的首选方法。

我遇到了同样的问题,出于我忽略的原因,不是在过去的项目中我做了完全相同的事情...... 经过一个小时的搜索,我意识到我的 table 'fos_user_user_group' 尚未创建,因为未创建映射。所以我的解决方案是简单地覆盖我的实体用户的组 属性 以定义 Doctrine ORM 映射:

/**
 * The User can have many groups.
 * @ORM\ManyToMany(targetEntity="Group")
 * @ORM\JoinTable(name="fos_user_user_group",
 *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
 *      )
 */
protected $groups;

之后,doctrine:schema:update --force 问题就解决了;)

如果您像我一样,先创建数据库,然后通过控制台创建 yml 文件,然后从中创建 类,那么您的注释就没用了。

Sonata 使用的是 yml 而不是注释。它们存在并且似乎有效,但它们就是无效。要生成 "Class does not exist" 消息,请检查您的 yml 定义在说什么。我需要在那里添加关系和实体 类。

如果这确实是您出错的原因,您可能希望通过删除或移动 yml 或 xml 模板到其他地方 (..\Resources\config\doctrine) 来激活注释 (..\Resources\config\doctrine)。