Итак, у меня есть собственный тип доктрины
пространство имен App \ Doctrine \ Types;
используйте Doctrine \ DBAL \ Platforms \ AbstractPlatform; используйте Doctrine \ DBAL \ Types \ TextType;
class MyType extends TextType
{
private $prefix='';
public function getName()
{
return 'my_type';
}
public function setPrefix(string $prefix)
{
$this->prefix=$prefix;
}
}
Я зарегистрировался в config / packages / doctrine.yml:
doctrine:
dbal:
types:
my_type: App\Doctrine\Types\MyType
Затем в Kernel boot () я пытаюсь добавить некоторые параметры к этому типу:
public function boot() {
parent::boot();
$myType=Type::getType('my_type');
$myType->setPrefix('abc');
}
Это отлично работает при первом запуске приложения. Префикс устанавливается для типа и может использоваться во всем приложении. Однако во второй раз я получаю исключение:
Unknown column type "encrypted_text" requested. Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database introspection then you might have forgotten to register all database types for a Doctrine Type. Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement Type#getMappedDatabaseTypes(). If the type name is empty you might have a problem with the cache or forgot some mapping information.
Затем я изменил boot () на:
public function boot() {
parent::boot();
if (!Type::hasType('my_type')) {
Type::addType('my_type', 'App\Doctrine\Types\MyType');
}
$myType=Type::getType('my_type');
$myType->setPrefix('abc');
}
Теперь исключение пропало, но префикс не установлен. Я знаю, что исключения дают мне информацию о том, что делать, но я действительно не знаю, с чего начать.
Может кто-то указать мне верное направление?
Увидел в таких вопросах: stackoverflow.com/questions/48154380/…. Метод setPrefix существует, и мне нужно передать префикс этого типа из файла конфигурации.
Я предполагаю, что вы вызываете parent :: boot () из своего метода загрузки?
да, сделал (отредактировал свой вопрос)
Просто сделайте полный снимок в темноте, но окружите свой код if ($ this-> booted === false) {и удалите кеш. Наверное, не поможет.
Большое спасибо за внимание к этому. К сожалению, это не работает. Исключение исчезло, но префикс больше не установлен. Итак, тип загружается нормально, и я могу его использовать, но у него нет префикса, установленного в boot (), поскольку он не выполняется (он выполняется при первом запуске приложения). Очистка кеша работает только один раз ...






На данный момент я исправил это, удалив его из config / packages / doctrine.yml, чтобы он больше там не регистрировался. Теперь я могу загрузить его в Kernel:
public function boot() {
parent::boot();
if (!Type::hasType('my_type')) {
Type::addType('my_type', 'App\Doctrine\Types\MyType');
}
$myType = Type::getType('my_type');
$myType->setPrefix('abc');
}
Я до сих пор не могу понять, почему это работает до создания кеша, но не после создания кеша. Но что ж, теперь я могу продолжить.
Если у кого-то есть лучший ответ, я был бы более чем счастлив принять его.
#This is may answer!!!
**IMPORTANTE!! Because in Symfony/PHP (NO Object Oriented Language) don't storaging a state it's need make this form to mapping an ENUM type or any Custom Type similary to ENUM.**
Для настройки и сопоставления типов, которые вы вводите как Enum в таблице DB, вам необходимо иметь более высокую версию Symfony> = 4.4 для использования этого Bundle. Выполните его в своем проекте (командная строка)
composer req fresh/doctrine-enum-bundle
Link example --> [https://github.com/fre5h/DoctrineEnumBundle][1] .
I made do this and it's ok for my app.
So, copy this class from this link
[https://github.com/fre5h/DoctrineEnumBundle/blob/master/DBAL/Types/AbstractEnumType.php][1]
and storage it in src/DBAL/Types =(IF NOT EXIST, CREATE IT), in your project Symfony => 4.4 o higher version.
#This is your Base class type.
Create this Table in Your Database (in my case I'm using MySql DB):
CREATE TABLE players (
id INT AUTO_INCREMENT NOT NULL,
position ENUM('PG', 'SG', 'SF', 'PF', 'C') NOT NULL,
PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = INNODB
*****************
Create an Entity class for mapping table (Players) from your Databae inside your project level directory.
D:SYMFONY\app\myApp
php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity --filter = "Players"
Create getter and setters for your new Entity:
D:SYMFONY\app\myApp
php bin/console make:entity --regenerate App
Generate your CRUD operation for Entty class + frontend.
D:SYMFONY\app\myApp
php bin/console make:entity --regenerate App
Create your custom Type class BasketballPositionType
<?php
namespace App\DBAL\Types;
use Fresh\DoctrineEnumBundle\DBAL\Types\AbstractEnumType;
final class BasketballPositionType extends AbstractEnumType
{
public const POINT_GUARD = 'PG';
public const SHOOTING_GUARD = 'SG';
public const SMALL_FORWARD = 'SF';
public const POWER_FORWARD = 'PF';
public const CENTER = 'C';
protected static $choices = [
self::POINT_GUARD => 'Point Guard',
self::SHOOTING_GUARD => 'Shooting Guard',
self::SMALL_FORWARD => 'Small Forward',
self::POWER_FORWARD => 'Power Forward',
self::CENTER => 'Center'
];
}
Go inside this path in your Symfony project at
D:SYMFONY\app\myApp\config\packages
and create this class php : doctrime.php.
This class it's necesary for to Register your new Type.
Can you find more information at link for register new type in synfony
[https://symfony.com/doc/current/doctrine/dbal.html][1]
so - REGISTER YOUR NEW TYPE
Copy this fragment of code end paste in doctrime.php class:
<?php
$container->loadFromExtension('doctrine', [
'dbal' => [
'mapping_types' => [
'enum' => 'string', /////////mapping enum to as stringa
],
'types' => [
'BasketballPositionType' => App\DBAL\Types\BasketballPositionType::class,
],
],
]);
So, bindig ENUM type db in String and your new Type is "BasketballPositionType" !!!!
Now, use your Custom Type in your Entity Class mapping 'Players'.
<?php
namespace App\Entity;
** very important
use App\DBAL\Types\BasketballPositionType;
use Fresh\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;
use Doctrine\ORM\Mapping as ORM;
/**
* Players
*
* @ORM\Table(name = "players")
* @ORM\Entity
*/
class Players
{
/**
* @var int
*
* @ORM\Column(name = "id", type = "integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy = "IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name = "position", type = "BasketballPositionType", length=255, nullable=false)
* @DoctrineAssert\Enum(entity = "App\DBAL\Types\BasketballPositionType")
*/
private $position;
public function getId(): ?int
{
return $this->id;
}
public function getPosition(): ?string
{
return $this->position;
}
public function setPosition(string $position): self
{
$this->position = $position;
return $this;
}
}
####################### RUM #######################
Run you Symfony embeded server
[ symfony serve ]
And go later in browser at https://127.0.0.1:8000/players
I'm use CMDER prompt command because it has Git incorporated.
It's very easy!!
[1]: https://symfony.com/doc/current/doctrine/dbal.html
Я не могу разобраться в вашем форматировании: что вы пытаетесь представить как?
Пожалуйста, добавьте всю информацию в свой ответ вместо ссылки на внешние ресурсы
Где вы видели документацию об использовании метода boot ()? Кажется немного необычным. По общему признанию, я никогда раньше не видел метода setPrefix. Вы уверены, что он вообще существует? Не вижу этого в базовом классе типа. Это один из ваших методов? Обычно я ожидал, что компилятор прошел бы для такого рода вещей.