Зарегистрируйте собственный тип Doctrine в Symfony4

Итак, у меня есть собственный тип доктрины

пространство имен 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');
   }

Теперь исключение пропало, но префикс не установлен. Я знаю, что исключения дают мне информацию о том, что делать, но я действительно не знаю, с чего начать.

Может кто-то указать мне верное направление?

Где вы видели документацию об использовании метода boot ()? Кажется немного необычным. По общему признанию, я никогда раньше не видел метода setPrefix. Вы уверены, что он вообще существует? Не вижу этого в базовом классе типа. Это один из ваших методов? Обычно я ожидал, что компилятор прошел бы для такого рода вещей.

Cerad 15.04.2018 16:04

Увидел в таких вопросах: stackoverflow.com/questions/48154380/…. Метод setPrefix существует, и мне нужно передать префикс этого типа из файла конфигурации.

Nin 15.04.2018 17:05

Я предполагаю, что вы вызываете parent :: boot () из своего метода загрузки?

Cerad 15.04.2018 17:17

да, сделал (отредактировал свой вопрос)

Nin 15.04.2018 18:12

Просто сделайте полный снимок в темноте, но окружите свой код if ($ this-> booted === false) {и удалите кеш. Наверное, не поможет.

Cerad 15.04.2018 19:33

Большое спасибо за внимание к этому. К сожалению, это не работает. Исключение исчезло, но префикс больше не установлен. Итак, тип загружается нормально, и я могу его использовать, но у него нет префикса, установленного в boot (), поскольку он не выполняется (он выполняется при первом запуске приложения). Очистка кеша работает только один раз ...

Nin 15.04.2018 20:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
4
6
2 972
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

На данный момент я исправил это, удалив его из 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.

1

    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.

2

    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
    *****************

3

    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"

4

    Create getter and setters for your new Entity:

    D:SYMFONY\app\myApp
    php bin/console make:entity --regenerate App 

5

    Generate your CRUD operation for Entty class + frontend.

    D:SYMFONY\app\myApp
    php bin/console make:entity --regenerate App 

6

 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'
    ];
}


7

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"  !!!!


8

    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

Я не могу разобраться в вашем форматировании: что вы пытаетесь представить как?

greybeard 18.03.2020 21:15

Пожалуйста, добавьте всю информацию в свой ответ вместо ссылки на внешние ресурсы

Nico Haase 16.06.2020 15:02

Другие вопросы по теме