作曲家需要本地包

Posted

技术标签:

【中文标题】作曲家需要本地包【英文标题】:Composer require local package 【发布时间】:2015-07-11 17:04:17 【问题描述】:

我有几个库 [Foo 和 Bar] 我正在共同开发,但在技术上仍然是独立的东西。以前我刚刚将自动加载器重新定义为喜欢"Foo\\": "../Foo/src",但现在我已经向 Foo 添加了 Guzzle 依赖项,Bar 翻转它的盖子,因为它不是它的依赖项之一。

目录结构:

/home/user/src/
    Foo/
        src/
            FooClient.php
        composer.json
    Bar/
        src/
            BarClient.php
        composer.json

理论自动加载语句:[in Bar/composer.json]

"require": 
    "local": "../Foo/composer.json"

示例代码:

require('vendor/autoload.php');

$f = new \Bar\BarClient(new \Foo\FooClient());

如何在不设置本地 Composer 存储库的情况下解决此问题?我想将这些作为单独的包进行维护,只是一个需要另一个,因此处理另一个的依赖项。

回答后编辑:

感谢 infomaniac,我完成了以下工作:

初始化 git repo:

cd ~/src/Foo && git init && echo -e "vendor\ncomposer.lock" > .gitignore && git add ./ && git commit -m "Initial Commit"

添加了作曲家配置:

"require": 
    "sammitch/foo": "dev-master"
,
"repositories": [
    "type": "vcs",
    "url": "/home/sammitch/src/Foo"
],

然后composer update!

【问题讨论】:

这个json如何指定对“sammitch/foo”的引用和“/home/sammitch/src/Foo”的地址之间的身份?是否遵循任何约定? @SebastiánGrignoli sammitch/foo 是包名,实际上与它所在的位置无关。将根据其配置的 repos 构建可用包的列表,在这种情况下,从指定的本地 git repo 获取 composer.json,然后由 composer 处理其余部分。 sammitch/foo 包被复制到当前应用的vendor 文件夹,与任何其他包相同。 哦,我想我现在明白了。它只是一个自定义 repo,就像在 APT 中一样,可能恰好包含“sammit/foo”包。我做对了吗? @SebastiánGrignoli 你打赌 【参考方案1】:

链接到本地​​开发包的方法是首先在主项目的composer.json 中添加一个存储库,如下所示:

"repositories": [
    
        "type": "path",
        "url": "/full/or/relative/path/to/development/package"
    
]

您还需要在您的开发包的composer.json 中指定一个版本,或者我这样做的方式是使用@dev 要求该包,如下所示:

composer require "vendorname/packagename @dev"

它应该输出:

- Installing vendor/packagename (dev-develop)
Symlinked from /full/or/relative/path/to/development/package

require 命令中的@dev 很重要,composer 使用它来获取源代码并将其符号链接到您的新包。

这是一个添加到版本约束的稳定性标志(请参阅package link)。

这些允许您进一步限制或扩展 超出minimum-stability 范围的包的稳定性 设置。

最低稳定性标志是:

可用选项(按稳定性排序)为 devalphabetaRCstable

【讨论】:

请注意,composer 不允许您指定与 composer.json 所在目录相同的路径。 有趣的一点,MaPePeR 我不知道这个。但是,我猜所有的 Web 框架已经通过将所有依赖项放入“供应商”文件夹来解决这个问题? Yii2 至少做到了这一点。 composer require "vendorname/packagename @dev" 在你的应用的 composer.json 中转换为 "require": "vendorname/packagename": "@dev" 如果你想运行 composer install 请添加:composer config repositories.local path /full/or/relative/path/to/development/package 作为添加存储库的正确方法 是否可以告诉作曲家将其安装到产品的供应商文件夹中而不是创建符号链接?【参考方案2】:

您可以使用 Composer 的 repositories 功能

https://getcomposer.org/doc/05-repositories.md#path


  "repositories": [
    
        "type": "path",
        "url": "../../packages/my-package"
    
  ],
  "require": 
    "my/package": "*"
  

不使用 http 格式,而是指定磁盘上的文件路径。

【讨论】:

marekkalnik.tumblr.com/post/22929686367/… getcomposer.org/doc/05-repositories.md#path 也很有用,似乎对我来说效果更好。 @JasmineHegman 确实!我也用过 - 非常适合开发 要让这个成为一个好的答案,您应该展示如何做到这一点,而不仅仅是命名功能并链接文档(尽管这也很重要)。下面的其他答案有适当的例子。【参考方案3】:

花了一些时间,我终于明白了解决方案。也许它对像我这样的人有用并且会节省你一些时间,所以我决定我必须在这里分享它。

假设你有以下目录结构(相对于你的项目根目录):

composer.json
config
config/composition-root.php
local
local/bar-project
local/bar-project/composer.json
local/bar-project/src
local/bar-project/src/Bar.php
public
public/index.php
src
src/Foo.php

在此示例中,您可能会看到 local 文件夹用于您公司的嵌套项目,例如bar-project。但如果您愿意,您可以配置任何其他布局。

每个项目都必须有自己的composer.json 文件,例如根composer.jsonlocal/bar-project/composer.json。那么它们的内容如下:

(根composer.json:)


  "name": "your-company/foo-project",
  "require": 
    "php": "^7",
    "your-company/bar-project": "@dev"
  ,
  "autoload": 
    "psr-4": 
      "YourCompany\\FooProject\\": "src/"
    
  ,
  "repositories": [
    
      "type": "path",
      "url": "local/bar-project"
    
  ]

(local/bar-project/composer.json:)


  "name": "your-company/bar-project",
  "autoload": 
    "psr-4": 
      "YourCompany\\BarProject\\": "src/"
    
  

例如,如果您希望将每个项目定位在单独的同级目录中,如下所示:

your-company
your-company/foo-project
your-company/foo-project/composer.json
your-company/foo-project/config
your-company/foo-project/config/composition-root.php
your-company/foo-project/public
your-company/foo-project/public/index.php
your-company/foo-project/src
your-company/foo-project/src/Foo.php
your-company/bar-project
your-company/bar-project/composer.json
your-company/bar-project/src
your-company/bar-project/src/Bar.php

- 然后你需要链接到repositories 部分中的相应目录:

  "repositories": [
    
      "type": "path",
      "url": "../bar-project"
    
  ]

在那之后不要忘记composer update(甚至rm -rf vendor && composer update -vthe docs suggest)! 在后台,composer 将创建一个vendor/your-company/bar-project 符号链接,指向local/bar-project(或../bar-project)。

假设您的public/index.php 只是一个front controller,例如:

<?php
require_once __DIR__ . '/../config/composition-root.php';

那么您的config/composition-root.php 将是:

<?php

declare(strict_types=1);

use YourCompany\BarProject\Bar;
use YourCompany\FooProject\Foo;

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

$bar = new Bar();
$foo = new Foo($bar);
$foo->greet();

【讨论】:

"rm -rf vendor/company/package" 很重要 @Alex83690 仅当您已经使用类似的composer.json 运行了composer update,因此您需要删除之前由 composer 创建的符号链接

以上是关于作曲家需要本地包的主要内容,如果未能解决你的问题,请参考以下文章

在 wordpress 插件中使用作曲家包

尝试在本地安装“Prestashop”但未正确安装 INTL

作曲家无法加载包无效的版本字符串

使用composer安装Drupal 8.x但使用本地镜像

强制 PHP 作曲家创建本地存储库的相对而非绝对符号链接

在我的本地主机中全局安装作曲家,现在我得到“file_put_contents(./composer.json):无法打开流:权限被拒绝”?