Symfony 4 中的私有自定义包位于何处?

Where do private, custom bundles live in 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/ 下。无论哪种方式,我最终都会遇到未定义的 class 错误。

我目前有:

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 Fatal error: Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "DSLLibraryBundle" from namespace "DSL\LibraryBundle".

几个注意事项:
- 我的自定义包不是通过 Composer 安装的
- 一旦我开始工作,实际的 DSL/ 目录将是一个符号链接

2017 年 1 月 30 日更新:

好的。据我所知,Symfony 4 实际上是敌对的私有包。

额外的工作不断出现越来越多的问题(比如让单元测试适用于私有包)。

我目前正在寻求不会导致太多额外日常工作的其他选择。

下面请忽略我原来的回答

--

我原来的回答:

经过更多的挖掘,我意识到我的自定义包目录树中的 类 在 dump-autoload 期间没有被 composer 拾取。

认为这是因为 Symfony 4 除了 vendor/.

之外不期待任何包

解决方案是将我的库目录添加到 composer.json。

所以我的项目树现在包含一个用于我的私人自定义包的目录。

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

我的 composer.json autoload.psr-4 条目现在看起来像这样:

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

Symfony4 不再在 src/ 中使用包。捆绑包仅在 vendor/ 中用作依赖项。

2019 年 4 月 12 日更新: 最后,我采用了与最初尝试完全不同的方法。
简而言之,我现在使用 composer 来包含我的自定义包。

我的自定义包位于它们自己的目录树中。
每个包必须有一个定义包的有效 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": "dpatterson@example.com"}],
  "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/ 中创建一个指向捆绑包的符号链接,然后一切都会按预期进行。

我的个人库是一个常规的 Symfony 项目,有一个包含我的包的 lib 子目录,每个包都在 lib/ 下的自己的子目录中。

Symfony 应用程序为我提供了一个方便的测试平台。请注意,自定义包必须包含在其中,就像任何其他 Symfony 项目一样。

@Stnaire,希望对您有所帮助。

它实际上并没有其他评论中描绘的那么糟糕 - 你仍然可以在 src/ 中拥有你的私有包,你只需要明确地将它们排除在自动装配之外,这样它们就不会被意外加载命名空间不正确。

假设您在 src/PrivateBundle 中有一个 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 错误。