w_b_x
@w_b_x

Нерешимая проблема с Symfony — как решить?

Происходит мистика. Мне нужно добавить в Symfony кастомное php приложение и было бы удобно обращаться к готовым объектам через Doctrine.
Код сначала работал, а потом почему-то появилась ошибка в проекте, причём её ранее не было, затем не сумев её одолеть пересоздал проект, установил в чистую папку Symfony Web Skeleton и с нуля один объект с помощью make:entity.

Код скрипта (лежит в _папка_проекта\worker\test.php):
<?php
require __DIR__.'/../vendor/autoload.php';
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
use App\Entity\Account; // Подключаю объект account, который прекрасно работает из Symfony

$isDevMode = true;
$entitiesPaths = array(__DIR__.'/../src/Entity');
$dbParams = array(
    'dbname' => 'база',
    'user' => 'логин',
    'password' => 'пароль',
    'host' => '127.0.0.1',
    'driver' => 'pdo_mysql',
);
$config = Setup::createAnnotationMetadataConfiguration($entitiesPaths, $isDevMode, null, null, false);
$em = EntityManager::create($dbParams, $config);
$id = 9; // для примера
$account = $em->getRepository(Account::class)->findOneBy([
    'id'=>$id,
]);
var_dump($account);


Получаю ошибку:
Fatal error: Uncaught TypeError: Argument 1 passed to App\Repository\AccountRepository::__construct() must be an instance of Symfony\Bridge\Doctrine\RegistryInterface, instance of Doctrine\ORM\EntityManager given, called in _папка_проекта_\vendor\doctrine\orm\lib\Doctrine\ORM\Repository\DefaultRepositoryFactory.php on line 68 and defined in _папка_проекта_\src\Repository\AccountRepository.php:17
Stack trace:
#0 _папка_проекта_\vendor\doctrine\orm\lib\Doctrine\ORM\Repository\DefaultRepositoryFactory.php(68): App\Repository\AccountRepository->__construct(Object(Doctrine\ORM\EntityManager), Object(Doctrine\ORM\Mapping\ClassMetadata))
#1 _папка_проекта_\vendor\doctrine\orm\lib\Doctrine\ORM\Repository\DefaultRepositoryFactory.php(50): Doctrine\ORM\Repository\DefaultRepositoryFactory->createRepository(Object(Doctrine\ORM\EntityManager), 'App\\Entity\\Acco...')
#2 _папка_проекта_\vendor\doctrine\orm\lib\Doctrine\ORM in_папка_проекта_\src\Repository\AccountRepository.php on line 17


Account Entity, Account Repository, Services.xml
Entity:
<?php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\AccountRepository")
 */
class Account
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $username;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $password;

    /**
     * @ORM\Column(type="integer", nullable=true)
     */
    private $status;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $status_title;

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

    /**
     * @ORM\Column(type="integer")
     */
    private $owner_id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $avatar;

    /**
     * @ORM\Column(type="boolean", nullable=true)
     */
    private $autopay;

    /**
     * @ORM\Column(type="integer")
     */
    private $worker_id;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getUsername(): ?string
    {
        return $this->username;
    }

    public function setUsername(string $username): self
    {
        $this->username = $username;

        return $this;
    }

    public function getPassword(): ?string
    {
        return $this->password;
    }

    public function setPassword(string $password): self
    {
        $this->password = $password;

        return $this;
    }

    public function getStatus(): ?int
    {
        return $this->status;
    }

    public function setStatus(?int $status): self
    {
        $this->status = $status;

        return $this;
    }

    public function getStatusTitle(): ?string
    {
        return $this->status_title;
    }

    public function setStatusTitle(?string $status_title): self
    {
        $this->status_title = $status_title;

        return $this;
    }

    public function getAccessDate(): ?\DateTimeInterface
    {
        return $this->access_date;
    }

    public function setAccessDate(?\DateTimeInterface $access_date): self
    {
        $this->access_date = $access_date;

        return $this;
    }

    public function getOwnerId(): ?int
    {
        return $this->owner_id;
    }

    public function setOwnerId(int $owner_id): self
    {
        $this->owner_id = $owner_id;

        return $this;
    }

    public function getAvatar(): ?string
    {
        return $this->avatar;
    }

    public function setAvatar(?string $avatar): self
    {
        $this->avatar = $avatar;

        return $this;
    }

    public function getAutopay(): ?bool
    {
        return $this->autopay;
    }

    public function setAutopay(?bool $autopay): self
    {
        $this->autopay = $autopay;

        return $this;
    }

    public function getWorkerId(): ?int
    {
        return $this->worker_id;
    }

    public function setWorkerId(int $worker_id): self
    {
        $this->worker_id = $worker_id;

        return $this;
    }
}


Repository:
<?php

namespace App\Repository;

use App\Entity\Account;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;

/**
 * @method Account|null find($id, $lockMode = null, $lockVersion = null)
 * @method Account|null findOneBy(array $criteria, array $orderBy = null)
 * @method Account[]    findAll()
 * @method Account[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class AccountRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Account::class);
    }

    // /**
    //  * @return Account[] Returns an array of Account objects
    //  */
    /*
    public function findByExampleField($value)
    {
        return $this->createQueryBuilder('a')
            ->andWhere('a.exampleField = :val')
            ->setParameter('val', $value)
            ->orderBy('a.id', 'ASC')
            ->setMaxResults(10)
            ->getQuery()
            ->getResult()
        ;
    }
    */

    /*
    public function findOneBySomeField($value): ?Account
    {
        return $this->createQueryBuilder('a')
            ->andWhere('a.exampleField = :val')
            ->setParameter('val', $value)
            ->getQuery()
            ->getOneOrNullResult()
        ;
    }
    */
}


Services.xml:
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
    locale: 'en'

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        public: false       # Allows optimizing the container by removing unused services; this also means
                            # fetching services directly from the container via $container->get() won't work.
                            # The best practice is to be explicit about your dependencies anyway.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']


packages/doctrine.yaml:
parameters:
    # Adds a fallback DATABASE_URL if the env var is not set.
    # This allows you to run cache:warmup even if your
    # environment variables are not available yet.
    # You should not need to change this value.
    env(DATABASE_URL): ''

doctrine:
    dbal:
        # configure these for your database server
        driver: 'pdo_mysql'
        server_version: '5.7'
        charset: utf8mb4
        default_table_options:
            charset: utf8mb4
            collate: utf8mb4_unicode_ci

        url: '%env(resolve:DATABASE_URL)%'
        types:
            json: Sonata\Doctrine\Types\JsonType
    orm:
        auto_generate_proxy_classes: true
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                type: annotation
                dir: '%kernel.project_dir%/src/Entity'
                prefix: 'App\Entity'
                alias: App



Выручайте
  • Вопрос задан
  • 2738 просмотров
Решения вопроса 1
BoShurik
@BoShurik Куратор тега Symfony
Symfony developer
Этот код будет работать только в Symfony
class AccountRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Account::class);
    }
}

Вам надо наследоваться от стандартного EntityRepository
class AccountRepository extends \Doctrine\ORM\EntityRepository
{

}


Чтобы в этом случае получить репозиторий из контейнера надо его описать через фабрику:
App\Repository\AccountRepository:
    arguments:
        - 'App\Entity\Account' # Entity class
    factory: ['@doctrine', 'getRepository']
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы