3

所以我不确定这里的问题是什么,或者这个类是如何被加载的。但我的模型(或实际称为实体)看起来像这样:

<?php

namespace ImageUploader\Models;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 * @UniqueEntity(fields="userName")
 * @UniqueEntity(fields="email")
 */
class User {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=32, nullable=false)
     * @Assert\NotBlank()
     */
    protected $firstName;

    /**
     * @ORM\Column(type="string", length=32, nullable=false)
     * @Assert\NotBlank()
     */
    protected $lastName;

    /**
     * @ORM\Column(type="string", length=100, unique=true, nullable=false)
     * @Assert\NotBlank(
     *    message = "Username cannot be blank"
     * )
     */
    protected $userName;

    /**
     * @ORM\Column(type="string", length=100, unique=true, nullable=false)
     * @Assert\NotBlank()
     * @Assert\Email(
     *    message = "The email you entered is invalid.",
     *    checkMX = true
     * )
     */
    protected $email;

    /**
     * @ORM\Column(type="string", length=500, nullable=false)
     * @Assert\NotBlank(
     *  message = "The password field cannot be empty."
     * )
     */
    protected $password;

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

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    protected $updated_at;
}

在我的我有一个调用的动作createAction,当用户尝试注册时会调用它。它看起来像这样:

public static function createAction($params){
  $postParams = $params->request()->post();

  if ($postParams['password'] !== $postParams['repassword']) {
    $flash = new Flash();
    $flash->createFlash('error', 'Your passwords do not match.');
    $params->redirect('/signup/error');
  }

  $user = new User();

  $user->setFirstName($postParams['firstname'])
       ->setLastName($postParams['lastname'])
       ->setUserName($postParams['username'])
       ->setEmail($postParams['email'])
       ->setPassword($postParams['password'])
       ->setCreatedAtTimeStamp();

  $validator = Validator::createValidatorBuilder();
  $validator->enableAnnotationMapping();

  $errors = $validator->getValidator()->validate($user);

  var_dump($errors);
}

调用此操作时,我收到以下错误:

Fatal error: Class 'doctrine.orm.validator.unique' not found in /var/www/html/image_upload_app/vendor/symfony/validator/ConstraintValidatorFactory.php on line 47

我不知道如何解决这个问题。我的作曲家文件是这样的:

{
  "require": {
    "doctrine/orm": "2.4.*",
    "doctrine/migrations": "1.0.*@dev",
    "symfony/validator": "2.8.*@dev",
    "symfony/doctrine-bridge": "2.8.*@dev",
    "slim/slim": "~2.6",
    "freya/freya-exception": "0.0.7",
    "freya/freya-loader": "0.2.2",
    "freya/freya-templates": "0.1.2",
    "freya/freya-factory": "0.0.8",
    "freya/freya-flash": "0.0.1"
  },
  "autoload": {
    "psr-4": {"": ""}
  }
}

所以我不确定我是否遗漏了一个包裹或者我做错了什么......

我的bootstrap.php文件中包含以下内容:

require_once 'vendor/autoload.php';

$loader = require 'vendor/autoload.php';
\Doctrine\Common\Annotations\AnnotationRegistry::registerLoader(array($loader, 'loadClass'));

use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

/**
 * Set up Doctrine.
 */
class DoctrineSetup {

    /**
     * @var array $paths - where the entities live.
     */
    protected $paths = array(APP_MODELS);

    /**
     * @var bool $isDevMode - Are we considered "in development."
     */
    protected $isDevMode = false;

    /**
     * @var array $dbParams - The database paramters.
     */
    protected $dbParams = null;

    /**
     * Constructor to set some core values.
     */
    public function __construct(){
        if (!file_exists('db_config.ini')) {
            throw new \Exception(
                'Missing db_config.ini. You can create this from the db_config_sample.ini'
            );
        }

        $this->dbParams = array(
            'driver' => 'pdo_mysql',
            'user' => parse_ini_file('db_config.ini')['DB_USER'],
            'password' => parse_ini_file('db_config.ini')['DB_PASSWORD'],
            'dbname' => parse_ini_file('db_config.ini')['DB_NAME']
        );
    }

    /**
     * Get the entity manager for use through out the app.
     *
     * @return EntityManager
     */
    public function getEntityManager() {
        $config = Setup::createAnnotationMetadataConfiguration($this->paths, $this->isDevMode, null, null, false);
        return EntityManager::create($this->dbParams, $config);
    }
}

/**
 * Function that can be called through out the app.
 *
 * @return EntityManager
 */
function getEntityManager() {
    $ds = new DoctrineSetup();
    return $ds->getEntityManager();
}

/**
 * Function that returns the conection to the database.
 */
function getConnection() {
    $ds = new DoctrineSetup();
    return $ds->getEntityManager()->getConnection();
}

我是否需要添加其他内容才能消除此错误?

更新 1

所以我继续设置,AppKernel因为我以前没有,因为我不相信我需要config.yml(至少现在还不需要)。一切似乎都在工作 - 内核明智,但错误仍然存​​在。

namespace ImageUploader;

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class AppKernel extends Kernel {

    public function registerBundles() {
        $bundles = array(
            new \Doctrine\Bundle\DoctrineBundle\DoctrineBundle()
        );

        return $bundles;
    }

    public function registerContainerConfiguration(LoaderInterface $loader) {}
}

然后我在引导文件中启动内核,添加:

use \ImageUploader\AppKernel;

$kernel = new AppKernel();
$kernel->boot();

从我读过的内容来看,一切都是正确的——减去不应该成为问题的丢失的配置文件。但我仍然收到有问题的错误

4

4 回答 4

4

我是如何解决这个问题的:

首先,创建了一个自定义 ConstraintValidatorFactory 允许我添加验证器

<?php
namespace My\App\Validator;

use Symfony\Component\Validator\ConstraintValidatorFactory as SymfonyConstraintValidatorFactory;
use Symfony\Component\Validator\ConstraintValidatorInterface;

/**
 * Class ConstraintValidatorFactory
 *
 * @package My\App\Validator
 */
class ConstraintValidatorFactory extends SymfonyConstraintValidatorFactory
{
    /**
     * @param string                       $className
     * @param ConstraintValidatorInterface $validator
     *
     * @return void
     */
    public function addValidator($className, $validator): void
    {
        $this->validators[$className] = $validator;
    }
}

然后我可以这样做:

<?php
use My\App\Validator\ConstraintValidatorFactory;
use Symfony\Component\Validator\Validation;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator;

$factory = new ConstraintValidatorFactory();
$factory->addValidator('doctrine.orm.validator.unique', new UniqueEntityValidator($registry));

$builder = Validation::createValidatorBuilder();
$builder->setConstraintValidatorFactory($factory);
$builder->enableAnnotationMapping();

$validator = $builder->getValidator();
$violations = $validator->validate($entity);

这对我有用,使用带有 zend 服务管理器的 symfony 组件。

请记住,Symfony 的 UniqueEntityValidator 依赖于 \Doctrine\Common\Persistence\ManagerRegistry.

我为我的项目使用了一个 EntityManager,并且必须将它包装在一个 ManagerRegistry 类中才能使其工作。

于 2018-04-15T11:51:28.697 回答
1

您缺少将教义集成到 Symfony 框架中的 Doctrine 捆绑包。安装它,composer require doctrine/doctrine-bundle然后在你的AppKernel.


与更新 #1 相关

您仍然需要一些配置并设置学说 ORM。如果没有此配置,将不会加载 ORM 服务(如此处缺少的服务)。

于 2015-05-02T22:31:26.713 回答
-1

在第一次你可以得到内核之后使用内核得到服务验证器。例如: $validator = $kernel->getContainer()->get('validator');

于 2019-12-26T09:56:42.333 回答
-1

这是一个老问题,但当我偶然发现它并发现选择的答案并不完全令人满意时,我想贡献一点。

正如我从评论中了解到的,这不是关于全栈 Symfony,而只是关于 Symfony-validator 组件。因为验证器约束 UniqueEntity 是基于 Doctrine 集成和硬编码类名,或者不建议使用此类来防止紧耦合,Symfony 使用了一种称为服务的常用模式(参见服务容器)。

这允许通过配置定义服务,然后防止将类名(及其依赖项!)硬编码到验证器代码库中。这允许两个项目之间的依赖关系是可配置的(更少的兼容性中断)和可选的。

这个正在搜索的“doctrine.orm.validator.unique”“类”实际上只是对实际类实例的引用。要找到它,必须添加两件事:

  • 一个服务容器,将这个服务名称解析为类实例
  • 以及该服务的实际配置,它定义了要实例化的类及其构造函数参数(依赖项)。

查看您的 composer.json 我认为我们需要Symfony DependencyInjection 组件,我认为您不需要 AppKernel 。以下代码可能有效(未经测试),但无论如何应该让您大致了解我们需要什么:

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container
    ->register('doctrine.orm.validator.unique', 'Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator')
    ->addArgument(new Reference('doctrine'));
# register doctrine here in the same way as we just registered the validator

因此,总而言之,对于 OP 来说,这个答案可能会迟到一两年,但可能对其他偶然发现这个问题的人有用。干杯!

于 2017-09-26T18:44:13.280 回答