это будет длинный пост, я столкнулся со странным поведением, когда я вижу в профилировщике, что один из менеджеров сущностей, как говорят, отображает сущность, но не отображает ее. Это выглядит так: Вот doctrine .yaml:
doctrine:
dbal:
default_connection: default
connections:
default:
driver: "pdo_mysql"
host: "127.0.0.1"
port: "3306"
dbname: "example"
user: "root"
password: ""
charset: utf8mb4
server_version: "mariadb-10.4.10"
logs:
driver: "pdo_mysql"
host: "127.0.0.1"
port: "3306"
dbname: "example_logs"
user: "root"
password: ""
charset: utf8mb4
server_version: "mariadb-10.4.10"
orm:
auto_generate_proxy_classes: true
default_entity_manager: default
entity_managers:
default:
query_cache_driver:
type: pool
pool: apcu.default.cache.pool
metadata_cache_driver:
type: pool
pool: apcu.default.cache.pool
result_cache_driver:
type: pool
pool: apcu.default.cache.pool
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Main'
prefix: 'App\Entity\Main'
alias: App
logs:
query_cache_driver:
type: pool
pool: apcu.default.cache.pool
metadata_cache_driver:
type: pool
pool: apcu.default.cache.pool
result_cache_driver:
type: pool
pool: apcu.default.cache.pool
connection: logs
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
LogBundle:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Logs'
prefix: 'App\Entity\Logs'
alias: App
А вот framework.yaml с конфигурацией пула кеша:
framework:
secret: '%env(APP_SECRET)%'
session:
handler_id: null
cookie_secure: auto
cookie_samesite: lax
php_errors:
log: true
cache:
pools:
apcu.default.cache.pool:
adapter: cache.adapter.apcu
apcu.logs.cache.pool:
adapter: cache.adapter.apcu
Если я удаляю конфигурацию metadata_cache_driver
из конфигурации журналов entity_manager
или изменяю ее для использования пула кэша (apcu.logs.cache.pool), отличного от менеджера сущностей по умолчанию, тогда профилировщик сообщает о правильных сопоставлениях (пример сущности в em по умолчанию и регистрирует их) пусто).
Эта проблема возникает только в том случае, если сущность является фидом через форму и $form->handleRequest()
обрабатывает ее, создание или изменение сущности без форм не вызывает такой проблемы. Вот мой контроллер:
<?php
namespace App\Controller;
use App\Entity\Main\Example;
use App\Form\Type\ExampleType;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ExampleController extends AbstractController {
/**
* @Route("/example1")
* @Template
*/
public function example1(EntityManagerInterface $em){
$example = new Example();
$example->setValue('example value');
try {
$em->persist($example);
$em->flush();
} catch(\Exception $e){
return new Response('An error has occurred. '.$e->getMessage());
}
return [];
}
/**
* @Route("/example2")
* @Template
*/
public function example2(EntityManagerInterface $em){
$example = $em->getRepository(Example::class)->find(1);
if(!$example){
return new Response('No example found.');
}
$example->setValue(mt_rand(0, mt_getrandmax()));
try {
$em->flush();
} catch(\Exception $e){
return new Response('An error has occurred. '.$e->getMessage());
}
return [];
}
/**
* @Route("/example3")
* @Template
*/
public function example3(Request $request, EntityManagerInterface $em){
$example = $em->getRepository(Example::class)->find(1);
if(!$example){
return new Response('No example found.');
}
$form = $this->createForm(ExampleType::class, $example);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$em->flush();
}
return ['form' => $form->createView()];
}
}
example1 и example2 маршруты НЕ вызывают проблему, только example3 делает и только при отправке формы, поэтому только когда я ввожу URL example3, затем нажмите Отправить форму только тогда, когда введите профилировщик для этого запроса, я вижу проблему.
Мой минимальный пример воспроизведения было создание symfony LTS проекта symfony new example-site --version=lts --full
Тогда это файлы, которые я изменились с тех пор:
Базы данных создаются symfony console doctrine:database:create --connection=default
и symfony console doctrine:database:create --connection=logs
, затем таблицы создаются symfony console doctrine:migrations:diff --em=default
и symfony console doctrine:migrations:migrate --em=default
Вот код для других файлов, которые я еще не включил в сообщение:
<?php
//src/Entity/Main/Example.php
namespace App\Entity\Main;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Example {
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
private $value;
public function getId(){
return $this->id;
}
public function getValue(){
return $this->value;
}
public function setValue(string $value){
$this->value = $value;
}
}
<?php
//src/Form/Type/ExampleType.php
namespace App\Form\Type;
use App\Entity\Main\Example;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ExampleType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options){
$builder->add('value', TextType::class);
$builder->add('submit', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver){
$resolver->setDefaults([
'data_class' => Example::class,
]);
}
}
<!-- template/s/example/example1.html.twig -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
Example1
</body>
</html>
<!-- template/s/example/example2.html.twig -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
Example2
</body>
</html>
<!-- template/s/example/example3.html.twig -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
{{ form(form) }}
</body>
</html>
Последнее, что я хочу добавить, это то, что в других спроецируйте эту проблему более отчетливо, потому что, когда у сущности есть ссылка на другую сущность, сообщается об ошибке (на стороне, не являющейся собственником в ассоциации со ссылками «один ко многим»): В этом случае Item сущность - это форма кормушки Для тех, кому любопытно, есть Item. php: Но я не знаю, как это будет иметь значение, так как он не управляется менеджером сущностей журналов и не должен отображаться под ним. Менеджер объекта по умолчанию, который управляет объектом, не сообщает о каких-либо проблемах с ним.
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity(repositoryClass="App\Repository\ItemRepository")
* @ORM\Table(indexes={
* @ORM\Index(name="item_image", columns={"image"})
* })
*/
class Item {
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=32)
* @Assert\NotBlank()
* @Assert\Length(min=3, max=32)
*/
private $name;
/**
* @ORM\Column(type="string")
*/
private $description = '';
/**
* @ORM\Column(type="string", length=25, nullable=true)
*/
private $image;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Item", mappedBy="container")
*/
private $items;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Item", inversedBy="items")
* @ORM\JoinColumn(name="container", referencedColumnName="id")
* @var $container Item
*/
private $container;
/**
* @ORM\OneToMany(targetEntity="App\Entity\TagItem", mappedBy="item")
* @var $tags TagItem[]
*/
private $tags;
/**
* @Assert\Image(mimeTypes="image/jpeg")
* @var $imageFile null|UploadedFile
*/
private $imageFile;
public function __construct() {
$this->items = new \Doctrine\Common\Collections\ArrayCollection();
$this->tags = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId(){
return $this->id;
}
public function getName(){
return $this->name;
}
public function setName(string $name){
$this->name = $name;
}
public function getDescription(){
return $this->description;
}
public function setDescription($description){
$this->description = $description;
}
public function hasImage(){
return isset($this->image);
}
public function getImage(){
return $this->image;
}
public function setImage($image){
$this->image = $image;
}
public function hasImageFile(){
return isset($this->imageFile);
}
public function getImageFile(){
return $this->imageFile;
}
public function setImageFile($imageFile){
$this->imageFile = $imageFile;
}
public function getItems(){
return $this->items;
}
public function hasContainer(){
return isset($this->container);
}
public function getContainer(){
return $this->container;
}
public function setContainer(?Item $container){
return $this->container = $container;
}
public function getTags(){
return $this->tags;
}
public function setTags($tags){
$this->tags = $tags;
}
}
PHP версия 7.3.12 и размещена с symfony serve