W
W
w_b_x2019-02-11 20:15:03
symfony
w_b_x, 2019-02-11 20:15:03

Unsolvable problem with Symfony - how to solve?

There is a mystic going on. I need to add a custom php application to Symfony and it would be convenient to access ready-made objects through Doctrine.
The code worked at first, and then for some reason an error appeared in the project, and it didn’t exist before, then, unable to overcome it, recreated the project, installed Symfony Web Skeleton in a clean folder and one object from scratch using make: entity.
Script code (located in _project_folder\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);

I am getting an error:
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


help out

Answer the question

In order to leave comments, you need to log in

1 answer(s)
B
BoShurik, 2019-02-11
@w_b_x

This code will only work in Symfony

class AccountRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Account::class);
    }
}

You need to inherit from the standard EntityRepository
class AccountRepository extends \Doctrine\ORM\EntityRepository
{

}

In this case, to get the repository from the container, you need to describe it through the factory:
App\Repository\AccountRepository:
    arguments:
        - 'App\Entity\Account' # Entity class
    factory: ['@doctrine', 'getRepository']

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question