php + symfony 5.0.x проблема автозагрузки при одновременном расширении абстрактного класса и реализации интерфейса - PullRequest
3 голосов
/ 23 января 2020

У меня есть symfony 5 проект.

И я столкнулся с проблемой автозагрузки.

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

I класс, абстрактный класс и интерфейс определены в одном и том же каталоге в одном и том же пространстве имен.

Проблема в том, что когда я описываю свой класс следующим образом:

class MyClass extends MyAbstractClass

class MyAbstractClass implements MyClassInterface

Я получаю ошибку автозагрузки:

Attempted to load class "MyClass" from namespace "App\Entities".  
Did you forget a "use" statement for another namespace? 

Строка из журналов:

Error thrown while running command "myproject:mycommand". Message: "Class 'App\Entities\MyClass' not found" ...

Если я использую:

class MyClass extends MyAbstractClass

или

class MyClass implements MyClassInterface

или

class MyClass extends MyAbstractClass implements MyClassInterface

тогда ошибка исчезла - все работает отлично.

Ошибка появляется, только если я использую

class MyAbstractClass implements MyClassInterface

Как решить проблему?

Мне нужно, чтобы этот абстрактный класс реализовывал интерфейс, поэтому любые классы, которые расширяют AbstractClass, будут совместимы с интерфейсом.

PHP 7.4.1 (cli)

1 Ответ

0 голосов
/ 24 января 2020

Проблема в порядке, файлы загружаются.

Я обнаружил проблему, бит я еще не исправил ее.

Проблема в том, что автозагрузчик включает файлы в алфавитный порядок, но не в порядке, файлы должны быть включены.

Мои настоящие имена классов:

AbstractEntity

EntityInterface

Ticket

Реализация:

interface EntityInterface {}

abstract class AbstractEntity implements EntityInterface {}

class Ticket extends AbstractEntity {}

Файлы включены в следующем порядке ( в алфавитном порядке ):

AbstractEntity.php

EntityInterface.php

Ticket.php

AbstractEntity.php - этот файл объявляет класс AbstractEntity.

Этот класс реализует интерфейс EntityInterface, поэтому файл EntityInterface.php должен быть уже включен до AbstractEntity.php.

правильный порядок должен быть:

EntityInterface.php

AbstractEntity.php

Ticket.php

Это легко проверить, просто переименовав от AbstractEntity до ObstractEntity, тогда алфавитный порядок будет:

EntityInterface.php

ObstractEntity.php

Ticket.php

Пока осталось только исправить порядок автозагрузки. Но ... Как это исправить быстро? Любые идеи? Это проблема с автозагрузкой поставщика или Symfony?

AFAIK В composer.json есть какая-то опция, которая гласит:

    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests/"
        }
    },

ОБНОВЛЕНИЕ : Хорошо, Я создал новый проект - и все работает хорошо. Работает как для каталога Entity, так и для Entities. Версии все одинаковые.

Но как только я переименовал Entites в Entity в моем исходном проекте - все начало работать без ошибок.

Так что это что-то странное.

Я могу только думать, что Symfony не настолько гибок, и классы должны храниться в каталоге Entity, тогда автозапуск работает хорошо.

На данный момент это

Ticket.php

AbstractEntity.php

EntityInterface.php

В том смысле, в каком они требуют друг друга.

...