一个共享供应商,有两个项目

时间:2015-05-02 08:25:46

标签: php symfony composer-php autoload vendor

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

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

project1/
project2/
shared_vendor/

我读到了这个。 我更改了app/autoload.php loader变量:

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

为:

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

我还更改了vendor-dir中的composer.json

    "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?

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

4 个答案:

答案 0 :(得分:5)

Composer基于每个项目工作。

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

我们与PEAR的“共享”供应商文件夹方法足够长,而且根本没有成功。使用全局供应商文件夹管理不同的项目需求是一件痛苦的事,因为每个项目都有不同的要求。

总之...

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

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

|-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文件。

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

答案 1 :(得分:0)

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

例如:

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

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

答案 2 :(得分:0)

对于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

答案 3 :(得分:0)

我知道这是一个老问题,但是我遇到了同样的问题。我正在使用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';

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

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

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

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