Поэтому я не уверен, в чем здесь проблема, или как этот класс даже загружается. Но моя модель (или как их на самом деле называют сущность) выглядит следующим образом:
<?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();
}
Нужно ли мне добавить что-то еще, чтобы эта ошибка исчезла?
Так что я пошел вперед и настроить 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();
Все, из того, что я прочитал, является правильным — за исключением отсутствующего файла конфигурации, который не должен быть проблемой. Но я все еще получаю ошибку, о которой идет речь
Вам не хватает пакета Doctrine, который интегрирует доктрину в среду Symfony. Установите его с composer require doctrine/doctrine-bundle
а затем зарегистрируйте его в своем AppKernel
,
Вам все еще нужна некоторая конфигурация и настройка доктрины ORM. Без этой конфигурации службы ORM (например, отсутствующие здесь) не загружаются.
Как я работал над этим:
Во-первых, создал пользовательский 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);
Это сработало для меня, используя компоненты Symfony с Zend Service Manager.
Имейте в виду, что UniqueEntityValidator Symfony зависит от \Doctrine\Common\Persistence\ManagerRegistry
,
Я использую один EntityManager для своего проекта и должен был обернуть его в классе ManagerRegistry, чтобы сделать эту работу.
Это старый вопрос, но, поскольку я только наткнулся на него и нахожу выбранный ответ не совсем удовлетворительным, я хотел бы внести свой вклад.
Как я понял из комментариев, речь идет не о Symfony с полным стеком, а только о компоненте Symfony-validator.
Поскольку ограничение валидатора UniqueEntity основано на интеграции Doctrine и жестко кодируемых именах классов, или что-то подобное не рекомендуется для предотвращения тесной связи, Symfony использует широко используемый шаблон, называемый services (см сервисный контейнер).
Это позволяет определять сервисы через конфигурацию, которая затем предотвращает жесткое кодирование имен классов (и их зависимостей!) В кодовую базу Validator. Это позволяет настраивать зависимости между обоими проектами (меньше нарушений совместимости) и необязательно.
Этот «класс» 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
Итак, в заключение, этот ответ, вероятно, будет на год или два слишком поздно для ФП, но может быть полезен для других, спотыкающихся об этом. Ура!