Где в Symfony 4 живут частные пользовательские пакеты?

У меня есть несколько частных настраиваемых пакетов, которые я использую в своих проектах Symfony. В Symfony 3 они жили в подкаталоге src:

src/
    DSL/
      DSLLibraryBundle/
      DSLTelnetBundle/
      ...
    SiteBundle/      # (or AppBundle)

В Symfony 4 пакет для конкретного приложения исчез, и мне неясно, где должны находиться мои пользовательские пакеты.

Документация по пакетам (https://symfony.com/doc/current/bundles/best_practices.html#bundles-naming-conventions) не содержат конкретных рекомендаций по размещению пользовательских пакетов.

Я попытался разместить свой каталог DSL непосредственно в каталоге проекта и в src /. В любом случае я получаю неопределенные ошибки класса.

В настоящее время у меня есть:

src/
    DSL/
        LibraryBundle/
            DSLLibraryBundle.php

Пакетный файл:

// src/DSL/DSLLibrary/DSLLibraryBundle.php:

namespace DSL\LibraryBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class DSLLibraryBundle extends Bundle
{

}

Запись в bundles.php:

DSL\LibraryBundle\DSLLibraryBundle::class => ['all' => true],

Текущая ошибка при запуске консольной команды:

Неустранимая ошибка PHP: Uncaught Symfony \ Component \ Debug \ Exception \ ClassNotFoundException: Попытка загрузить класс «DSLLibraryBundle» из пространства имен «DSL \ LibraryBundle».

Несколько примечаний:
- Мои пользовательские пакеты не устанавливаются через Composer.
- Фактический каталог DSL / будет символической ссылкой, как только я получу эту работу


person David Patterson    schedule 25.01.2018    source источник


Ответы (4)


Обновление от 12 апреля 2019 г .: В конце концов, я выбрал совершенно иной подход, нежели мои первоначальные попытки.
Вкратце, теперь я использую композитор для включения своих пользовательских пакетов.

Мои пользовательские пакеты живут в собственном дереве каталогов.
Каждый пакет должен иметь действительный файл composer.json, определяющий пакет. Например:

{
  "name": "dsl/base-bundle",
  "description": "Base bundle required by all other DSL bundles",
  "type": "symfony-bundle",
  "version": "2.1.0",
  "license": "proprietary",
  "authors": [{"name": "David M. Patterson", "email": "[email protected]"}],
  "minimum-stability": "stable",
  "require": {
  },
  "require-dev": {
  },
  "autoload": {
    "psr-4":  {
      "Dsl\\BaseBundle\\": "src/"
    }
  }
}

Затем определите настраиваемый репозиторий в файле проекта composer.json:

"repositories":[
  {
    "type": "path",
    "url":  "/full/path/to/DslBaseBundle"
  },
 ], ...

Затем сделайте, чтобы композитор требовал dsl / base-bundle.
Composer создаст символическую ссылку в vendor / to the bundle, и оттуда все будет работать так, как ожидалось.

Моя личная библиотека - это обычный проект Symfony с подкаталогом lib, который содержит мои пакеты, каждый в своем собственном подкаталоге ниже lib /.

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

@Stnaire, надеюсь, это поможет.

person David Patterson    schedule 12.04.2019

Обновление от 30 января 2017 г .:

Хорошо. Насколько я могу судить, Symfony 4, по сути, является враждебным частным пакетам.

Дополнительная работа продолжала вызывать все больше и больше проблем (например, заставить модульное тестирование работать для частного пакета).

В настоящее время я ищу другие варианты, которые не потребуют слишком много дополнительной ежедневной работы.

Пожалуйста, проигнорируйте мой исходный ответ ниже.

--

Мой исходный ответ:

Еще немного покопавшись, я понял, что классы в моем собственном дереве каталогов пакетов не были взяты композитором во время автоматической загрузки дампа.

Я думаю, что это потому, что Symfony 4 не ожидает никаких пакетов, кроме vendor /.

Решением было добавить каталог моей библиотеки в composer.json.

Итак, мое дерево проектов теперь содержит каталог для моих частных пользовательских пакетов.

<projectName>/
    assets/
    ...
    DSL/
        DSLLibraryBundle/
        DSLTelnetBundle/
        ...
    public/
    src/
    ...

Моя запись composer.json autoload.psr-4 теперь выглядит так:

"autoload": {
    "psr-4": {
        "App\\": "src/",
        "DSL\\": "DSL/"
    }
},
person David Patterson    schedule 25.01.2018
comment
У вас есть новости по этому поводу? У меня такой же случай с несколькими частными пакетами, которые я повторно использую в нескольких проектах, я ищу чистый способ сохранить их при обновлении до sf4. - person Stnaire; 10.04.2019

На самом деле это не так плохо, как написано в других комментариях - вы все равно можете иметь свои частные пакеты внутри src/, вам просто нужно явно исключить их из автосоединения, чтобы они не были случайно загружены с неправильным пространством имен.

Допустим, у вас есть PrivateBundle в src/PrivateBundle.

Вы настраиваете автозагрузку в composer.json вот так:

"autoload": {
  "psr-4": {
    "App\\": "src/",
    "SomeNamespace\\PrivateBundle\\": "src/PrivateBundle/"
  }
}

и в конфигурации ваших сервисов (я обычно использую config/services.yaml) сделайте следующее:

# 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/PrivateBundle'

Если вы не добавите это исключение, ваши SomeNamespace\PrivateBundle\* классы автоматически загружаются Symfony как App\PrivateBundle\*, но содержат namespace SomeNamespace\PrivateBundle;, поэтому, когда PHP обнаруживает использование SomeNamespace\PrivateBundle, он автоматически загружает их снова через Composer, что приводит к Cannot declare class *, because the name is already in use ошибкам.

person Kick_the_BUCKET    schedule 01.04.2021
comment
Спасибо! Я попробую в следующий раз, когда буду работать над проектом Symfony. - person David Patterson; 02.04.2021

Symfony4 больше не использует пакеты внутри src /. Пакеты используются только внутри поставщика / как зависимости.

person Tim Lieberman    schedule 25.01.2018
comment
да. Это в значительной степени так. Однако вы можете создавать частные пакеты, которых нет в vendor /. Смотрите мой ответ. Спасибо. - person David Patterson; 26.01.2018