【问题标题】:One shared vendor with two projects一个共享供应商有两个项目
【发布时间】:2015-07-12 01:32:09
【问题描述】:

我现在正在处理 2 个应用程序。第一个是CMS,第二个是商店。我想将我的供应商提升一级并在项目之间共享。

所以我的结构会是这样的:

project1/
project2/
shared_vendor/

我读到了这个。 我已将app/autoload.php loader 变量从:

$loader = require __DIR__.'/../vendor/autoload.php';

到:

$loader = require __DIR__.'/../../vendor/autoload.php';

而且我的composer.json 中的vendor-dir 也从:

    "config": {
      "bin-dir": "bin",
      "vendor-dir": "vendor"
    },

到:

    "config": {
      "bin-dir": "bin",
      "vendor-dir": "/../vendor"
    },

在此之后我收到此错误:

ClassNotFoundException in AppKernel.php line 20: Attempted to load 
class "CmsUserBundle" from namespace "Cms\UserBundle".
Did you forget a "use" statement for another namespace?

我做错了什么?我忘了改变什么吗? 提前致谢。

【问题讨论】:

  • CmsUserBundle 是否存在于project_1/src/shared_vendor/ 中?
  • 您缺少手动编辑加载项目命名空间的作曲家自动加载配置。
  • 您为什么要这样做?拥有两个使用相同供应商的独立系统意味着您必须将两个包依赖项保持在相同的版本。
  • @WouterJ 是的,CmsUserBundle 在 project1/src 中。
  • @code-jaff,我应该在作曲家中准确地改变什么?

标签: php symfony composer-php autoload vendor


【解决方案1】:

Composer 在每个项目的基础上工作。

一个项目 - 一个供应商文件夹。不是,两个项目和一个“共享”供应商文件夹。

我们使用 PEAR 的“共享”供应商文件夹方法已经够久了,但它根本行不通。使用全局供应商文件夹管理不同的项目需求是一件很痛苦的事情,因为每个项目都有不同的需求。

无论如何...

如果您喜欢“共享供应商文件夹”设置,我建议创建类似于“包装器”或“超级”项目的东西,作为其他两个项目的容器存储库。包装项目将包含composer.json 文件,其中包含两个(!)项目的要求。这意味着您在两个子项目中使用相同的依赖项集。

这允许定义两个子项目(cms 和 shop)的要求 在“包装器”回购中。基本上,我建议采用以下结构:

|-container-project
  +-CMS
    |-src
    +-tests
  +-Shop
    |-src
    +-tests
  +-vendors      // contains dependencies for both projects (CMS + Shop)
|-composer.json  // define requirements for both projects

此设置也允许为子项目引入composer.json 文件。 您只需将需求从超级项目的composer.json 文件转移到子项目的composer.json 文件中。

现在,还可以通过按特定顺序注册自动加载器来调整子项目的自动加载行为。

【讨论】:

  • 好的,谢谢解释。正如你们所写的,我将为一个项目使用一个供应商。 :)
【解决方案2】:

根据您的要求,如果您需要/想要在多个项目之间共享的唯一内容是供应商目录,您可以在每个项目中创建符号链接,除了已经拥有供应商目录的主要项目。

例如:

cd /var/www/SiteA
composer install
# git clone new project into /var/www/SiteB
cd ../SiteB
# If vendor directory is already there, delete it: rm -rf vendor
# create symlink to Site A's vendor directory
ln -s /var/www/SiteA/vendor

除非您确定所有项目都肯定需要完全相同版本的依赖项,否则这可能不是一个好计划。

【讨论】:

    【解决方案3】:

    适用于 Laravel 5、6 和 7+

    添加新的供应商文件夹配置后:

    ...
    "config": {
        ...,
        "vendor-dir": "../vendor"
    },
    ...
    

    然后运行composer update

    那你需要改两个文件:

    1. 对于您的应用:public/index.php

      require __DIR__.'/../../vendor/autoload.php';

    2. 根文件夹中您的工匠命令:artisan

      require __DIR__.'/../vendor/autoload.php';

    3. Illuminate\Foundation\PackageManifest 中的包自动发现:

      $this->vendorPath = $basePath.'/../vendor'; //Change this line in constructor

    然后重新运行

    php artisan package:discover --ansi
    

    【讨论】:

      【解决方案4】:

      我知道这是一个老问题,但我遇到了同样的问题。我正在使用 Laravel 7,并通过以下方法解决了问题。
      我使用以下代码在项目的根目录中编写了一个 shellscript (my-vendor.sh):

       #!/bin/bash
      
      MY_VENDOR_DIRECTORY=my-vendor
      VENDOR_DIRECTORY=vendor
      
      if [ ! -d "$MY_VENDOR_DIRECTORY" ]
      then
        echo "Le dossier $MY_VENDOR_DIRECTORY n'existe pas : on le crée."
        mkdir "$MY_VENDOR_DIRECTORY"
      else
        echo "Le dossier $MY_VENDOR_DIRECTORY existe : on le vide."
        rm -rf "$MY_VENDOR_DIRECTORY/*"
      fi
      
      echo "Copie des fichiers autoload généré depuis $VENDOR_DIRECTORY vers $MY_VENDOR_DIRECTORY."
      cp "$VENDOR_DIRECTORY/autoload.php" "$MY_VENDOR_DIRECTORY"
      cp -R "$VENDOR_DIRECTORY/composer" "$MY_VENDOR_DIRECTORY"
      
      cd "$MY_VENDOR_DIRECTORY/composer"
      
      echo "Remplacement de 'require \$file' par \str_replace(\"$MY_VENDOR_DIRECTORY\/composer\/..\", \"vendor\", \$file)"
      sed -i "s/require \$file/require \\str_replace('$MY_VENDOR_DIRECTORY\/composer\/..', 'vendor', \$file)/" autoload_real.php
      
      echo "Remplacement de 'include \$file' par \str_replace(\"$MY_VENDOR_DIRECTORY\/composer\/..\", \"vendor\", \$file) "
      sed -i "s/include \$file/require \\str_replace('$MY_VENDOR_DIRECTORY\/composer\/..', 'vendor', \$file)/" ClassLoader.php
      

      然后,我将public/index.php中的以下代码替换为:

      • require __DIR__.'/../vendor/autoload.php' => require __DIR__.'/../my-vendor/autoload.php';

      之后,我在post-autoload-dump 脚​​本中添加my-vendor.sh 命令。

      我在我的两个项目中进行了此修改,启动 composer dump-autoload,它就像一个魅力 :)

      要点链接:https://gist.github.com/flibidi67/7c2cfdc1ff1b977b48204be0bee5eb76

      希望这可以帮助其他人;)

      【讨论】:

        猜你喜欢
        • 2012-03-02
        • 1970-01-01
        • 2011-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多